code:
#ifndef GUARD_TRAINER_REMATCH_H
#define GUARD_TRAINER_REMATCH_H

enum {
    REMATCH_ROSE,
    REMATCH_ANDRES,
    REMATCH_DUSTY,
    REMATCH_LOLA,
    REMATCH_RICKY,
    REMATCH_LILA_AND_ROY,
    REMATCH_CRISTIN,
    REMATCH_BROOKE,
    REMATCH_WILTON,
    REMATCH_VALERIE,
    REMATCH_CINDY,
    REMATCH_THALIA,
    REMATCH_JESSICA,
    REMATCH_WINSTON,
    REMATCH_STEVE,
    REMATCH_TONY,
    REMATCH_NOB,
    REMATCH_KOJI,
    REMATCH_FERNANDO,
    REMATCH_DALTON,
    REMATCH_BERNIE,
    REMATCH_ETHAN,
    REMATCH_JOHN_AND_JAY,
    REMATCH_JEFFREY,
    REMATCH_CAMERON,
    REMATCH_JACKI,
    REMATCH_WALTER,
    REMATCH_KAREN,
    REMATCH_JERRY,
    REMATCH_ANNA_AND_MEG,
    REMATCH_ISABEL,
    REMATCH_MIGUEL,
    REMATCH_TIMOTHY,
    REMATCH_SHELBY,
    REMATCH_CALVIN,
    REMATCH_ELLIOT,
    REMATCH_ISAIAH,
    REMATCH_MARIA,
    REMATCH_ABIGAIL,
    REMATCH_DYLAN,
    REMATCH_KATELYN,
    REMATCH_BENJAMIN,
    REMATCH_PABLO,
    REMATCH_NICOLAS,
    REMATCH_ROBERT,
    REMATCH_LAO,
    REMATCH_CYNDY,
    REMATCH_MADELINE,
    REMATCH_JENNY,
    REMATCH_DIANA,
    REMATCH_AMY_AND_LIV,
    REMATCH_ERNEST,
    REMATCH_CORY,
    REMATCH_EDWIN,
    REMATCH_LYDIA,
    REMATCH_ISAAC,
    REMATCH_GABRIELLE,
    REMATCH_CATHERINE,
    REMATCH_JACKSON,
    REMATCH_HALEY,
    REMATCH_JAMES,
    REMATCH_TRENT,
    REMATCH_SAWYER,
    REMATCH_KIRA_AND_DAN,
    REMATCH_WALLY_3,  // Entries above WALLY are considered normal trainers, from Wally below are special trainers
    REMATCH_ROXANNE,
    REMATCH_BRAWLY,
    REMATCH_WATTSON,
    REMATCH_FLANNERY,
    REMATCH_NORMAN,
    REMATCH_WINONA,
    REMATCH_TATE_AND_LIZA,
    REMATCH_JUAN,
    REMATCH_SIDNEY, // Entries below SIDNEY are considered part of REMATCH_ELITE_FOUR_ENTRIES.
    REMATCH_PHOEBE,
    REMATCH_GLACIA,
    REMATCH_DRAKE,
    REMATCH_WALLACE,
    REMATCH_TABLE_ENTRIES // The total number of rematch entries. Must be last in enum
};

#define REMATCH_SPECIAL_TRAINER_START   REMATCH_WALLY_3
#define REMATCH_ELITE_FOUR_ENTRIES      REMATCH_SIDNEY

void UpdateGymLeaderRematch(void);

#endif //GUARD_TRAINER_REMATCH_H

repo_name: Lunos/pokeemerald

license: mit


code:
#ifndef GUARD_HALL_OF_FAME_H
#define GUARD_HALL_OF_FAME_H

void CB2_DoHallOfFameScreen(void);
void CB2_DoHallOfFameScreenDontSaveData(void);
void CB2_DoHallOfFamePC(void);

// hof_pc.c
void ReturnFromHallOfFamePC(void);

#endif // GUARD_HALL_OF_FAME_H


code:
#ifndef GUARD_HEAL_LOCATION_H
#define GUARD_HEAL_LOCATION_H

struct HealLocation
{
    s8 group;
    s8 map;
    u16 x;
    u16 y;
};

u32 GetHealLocationIndexByMap(u16 mapGroup, u16 mapNum);
const struct HealLocation *GetHealLocationByMap(u16 mapGroup, u16 mapNum);
const struct HealLocation *GetHealLocation(u32 index);

#endif // GUARD_HEAL_LOCATION_H


code:
#ifndef GUARD_IMAGE_PROCESSING_EFFECTS_H
#define GUARD_IMAGE_PROCESSING_EFFECTS_H

enum
{
    IMAGE_EFFECT_POINTILLISM = 2,
    IMAGE_EFFECT_GRAYSCALE_LIGHT = 6,
    IMAGE_EFFECT_BLUR = 8,
    IMAGE_EFFECT_OUTLINE_COLORED = 9,
    IMAGE_EFFECT_INVERT_BLACK_WHITE = 10,
    IMAGE_EFFECT_THICK_BLACK_WHITE = 11,
    IMAGE_EFFECT_SHIMMER = 13,
    IMAGE_EFFECT_OUTLINE = 30,
    IMAGE_EFFECT_INVERT = 31,
    IMAGE_EFFECT_BLUR_RIGHT = 32,
    IMAGE_EFFECT_BLUR_DOWN = 33,
    IMAGE_EFFECT_CHARCOAL = 36,
};

enum
{
    QUANTIZE_EFFECT_STANDARD,
    QUANTIZE_EFFECT_STANDARD_LIMITED_COLORS,
    QUANTIZE_EFFECT_PRIMARY_COLORS,
    QUANTIZE_EFFECT_GRAYSCALE,
    QUANTIZE_EFFECT_GRAYSCALE_SMALL,
    QUANTIZE_EFFECT_BLACK_WHITE,
};

struct ImageProcessingContext
{
    u8 effect;
    void *canvasPixels;
    u16 *canvasPalette;
    u8 fillerC[0x4];
    void *dest;
    u16 quantizeEffect;
    u16 var_16;
    u8 paletteStart;
    u8 columnStart;
    u8 rowStart;
    u8 columnEnd;
    u8 rowEnd;
    u8 canvasWidth;
    u8 canvasHeight;
    u8 personality;
};

void ApplyImageProcessingEffects(struct ImageProcessingContext *);
void ApplyImageProcessingQuantization(struct ImageProcessingContext *);
void ConvertImageProcessingToGBA(struct ImageProcessingContext *);

#endif


code:
#ifndef GUARD_INTERNATIONAL_STRING_UTIL_H
#define GUARD_INTERNATIONAL_STRING_UTIL_H

#include "menu.h"
#include "list_menu.h"

void sub_81DB52C(u8 *src);
void TVShowConvertInternationalString(u8 *dest, const u8 *src, int language);
int GetStringCenterAlignXOffset(int fontId, const u8 *str, int totalWidth);
int GetStringRightAlignXOffset(int fontId, const u8 *str, int totalWidth);
int GetStringCenterAlignXOffsetWithLetterSpacing(int fontId, const u8 *str, int totalWidth, int letterSpacing);
int GetStringWidthDifference(int fontId, const u8 *str, int totalWidth, int letterSpacing);
int GetMaxWidthInMenuTable(const struct MenuAction *str, int arg1);
int sub_81DB3D8(const struct MenuAction *str, const u8* arg1, int arg2);
int Intl_GetListMenuWidth(const struct ListMenuTemplate *listMenu);
void CopyMonCategoryText(int dexNum, u8 *dest);
u8 *sub_81DB494(u8 *str, int fontId, const u8 *str2, int totalStringWidth);
void PadNameString(u8 *dest, u8 padChar);
void sub_81DB554(u8 *, u8);
void sub_81DB5AC(u8 *);
int sub_81DB604(u8 *);
void sub_81DB620(int windowId, int columnStart, int rowStart, int numFillTiles, int numRows);

#endif // GUARD_INTERNATIONAL_STRING_UTIL_H


code:
#ifndef GUARD_INTRO_H
#define GUARD_INTRO_H

// Exported type declarations

// Exported RAM declarations

// Exported ROM declarations
void CB2_InitCopyrightScreenAfterBootup(void);
void CB2_InitCopyrightScreenAfterBootup(void);
void CB2_InitCopyrightScreenAfterTitleScreen(void);
void PanFadeAndZoomScreen(u16, u16, u16, u16);

#endif // GUARD_INTRO_H


code:
#ifndef GUARD_INTRO_CREDITS_GRAPHICS_H
#define GUARD_INTRO_CREDITS_GRAPHICS_H

extern u16 gUnknown_0203BD24;
extern s16 gUnknown_0203BD26;
extern s16 gUnknown_0203BD28;

extern const struct CompressedSpriteSheet gIntro2BrendanSpriteSheet[];
extern const struct CompressedSpriteSheet gIntro2MaySpriteSheet[];
extern const struct CompressedSpriteSheet gIntro2BicycleSpriteSheet[];
extern const struct CompressedSpriteSheet gIntro2FlygonSpriteSheet[];
extern const struct SpritePalette gIntroBikeAndFlygonPalette[];
extern const struct CompressedSpriteSheet gUnknown_085F5334[];
extern const struct CompressedSpriteSheet gUnknown_085F5344[];
extern const struct CompressedSpriteSheet gUnknown_085F5354[];
extern const struct CompressedSpriteSheet gUnknown_085F53AC[];
extern const struct CompressedSpriteSheet gUnknown_085F53BC[];
extern const struct SpritePalette gUnknown_085F5384[];

void load_intro_part2_graphics(u8 a);
void sub_817B150(u8 a);
void sub_817B1C8(u8);
void sub_817B3A8(u8);
u8 CreateBicycleAnimationTask(u8 a, u16 b, u16 c, u16 d);
void sub_817B540(u8);
u8 intro_create_brendan_sprite(s16 a, s16 b);
u8 intro_create_may_sprite(s16 a, s16 b);
u8 intro_create_flygon_sprite(s16 a, s16 b);

#endif // GUARD_INTRO_CREDITS_GRAPHICS_H


code:
#ifndef GUARD_ITEM_H
#define GUARD_ITEM_H

#include "constants/item.h"

typedef void (*ItemUseFunc)(u8);

struct Item
{
    u8 name[ITEM_NAME_LENGTH];
    u16 itemId;
    u16 price;
    u8 holdEffect;
    u8 holdEffectParam;
    const u8 *description;
    u8 importance;
    u8 unk19;
    u8 pocket;
    u8 type;
    ItemUseFunc fieldUseFunc;
    u8 battleUsage;
    ItemUseFunc battleUseFunc;
    u8 secondaryId;
};

struct BagPocket
{
    struct ItemSlot *itemSlots;
    u8 capacity;
};

extern struct BagPocket gBagPockets[];

void ApplyNewEncryptionKeyToBagItems(u32 newKey);
void ApplyNewEncryptionKeyToBagItems_(u32 newKey);
void SetBagItemsPointers(void);
void CopyItemName(u16 itemId, u8 *dst);
void CopyItemNameHandlePlural(u16 itemId, u8 *dst, u32 quantity);
void GetBerryCountString(u8 *dst, const u8 *berryName, u32 quantity);
bool8 IsBagPocketNonEmpty(u8 pocket);
bool8 CheckBagHasItem(u16 itemId, u16 count);
bool8 HasAtLeastOneBerry(void);
bool8 CheckBagHasSpace(u16 itemId, u16 count);
bool8 AddBagItem(u16 itemId, u16 count);
bool8 RemoveBagItem(u16 itemId, u16 count);
u8 GetPocketByItemId(u16 itemId);
void ClearItemSlots(struct ItemSlot *itemSlots, u8 itemCount);
u8 CountUsedPCItemSlots(void);
bool8 CheckPCHasItem(u16 itemId, u16 count);
bool8 AddPCItem(u16 itemId, u16 count);
void RemovePCItem(u8 index, u16 count);
void CompactPCItems(void);
void SwapRegisteredBike(void);
u16 BagGetItemIdByPocketPosition(u8 pocketId, u16 pocketPos);
u16 BagGetQuantityByPocketPosition(u8 pocketId, u16 pocketPos);
void CompactItemsInBagPocket(struct BagPocket *bagPocket);
void SortBerriesOrTMHMs(struct BagPocket *bagPocket);
void MoveItemSlotInList(struct ItemSlot* itemSlots_, u32 from, u32 to_);
void ClearBag(void);
u16 CountTotalItemQuantityInBag(u16 itemId);
bool8 AddPyramidBagItem(u16 itemId, u16 count);
bool8 RemovePyramidBagItem(u16 itemId, u16 count);
const u8 *ItemId_GetName(u16 itemId);
u16 ItemId_GetId(u16 itemId);
u16 ItemId_GetPrice(u16 itemId);
u8 ItemId_GetHoldEffect(u16 itemId);
u8 ItemId_GetHoldEffectParam(u16 itemId);
const u8 *ItemId_GetDescription(u16 itemId);
u8 ItemId_GetImportance(u16 itemId);
u8 ItemId_GetUnknownValue(u16 itemId);
u8 ItemId_GetPocket(u16 itemId);
u8 ItemId_GetType(u16 itemId);
ItemUseFunc ItemId_GetFieldFunc(u16 itemId);
u8 ItemId_GetBattleUsage(u16 itemId);
ItemUseFunc ItemId_GetBattleFunc(u16 itemId);
u8 ItemId_GetSecondaryId(u16 itemId);

#endif // GUARD_ITEM_H


code:
#ifndef GUARD_ITEM_ICON_H
#define GUARD_ITEM_ICON_H

extern void *gItemIconDecompressionBuffer;
extern void *gItemIcon4x4Buffer;

extern const struct SpriteTemplate gItemIconSpriteTemplate;

bool8 AllocItemIconTemporaryBuffers(void);
void FreeItemIconTemporaryBuffers(void);
void CopyItemIconPicTo4x4Buffer(const void *src, void *dest);
u8 AddItemIconSprite(u16 tilesTag, u16 paletteTag, u16 itemId);
u8 AddCustomItemIconSprite(const struct SpriteTemplate *customSpriteTemplate, u16 tilesTag, u16 paletteTag, u16 itemId);
const void *GetItemIconPicOrPalette(u16 itemId, u8 which);

#endif //GUARD_ITEM_ICON_H


code:
#ifndef GUARD_item_menu_H
#define GUARD_item_menu_H

#include "item.h"
#include "menu_helpers.h"

#define ITEMMENULOCATION_FIELD 0
#define ITEMMENULOCATION_BATTLE 1
#define ITEMMENULOCATION_PARTY 2
#define ITEMMENULOCATION_SHOP 3
#define ITEMMENULOCATION_BERRY_TREE 4
#define ITEMMENULOCATION_BERRY_BLENDER_CRUSH 5
#define ITEMMENULOCATION_ITEMPC 6
#define ITEMMENULOCATION_FAVOR_LADY 7
#define ITEMMENULOCATION_QUIZ_LADY 8
#define ITEMMENULOCATION_APPRENTICE 9
#define ITEMMENULOCATION_WALLY 10
#define ITEMMENULOCATION_PCBOX 11
#define ITEMMENULOCATION_LAST 12

#define ITEMMENUACTION_USE           0
#define ITEMMENUACTION_TOSS          1
#define ITEMMENUACTION_REGISTER      2
#define ITEMMENUACTION_GIVE          3
#define ITEMMENUACTION_CANCEL        4
#define ITEMMENUACTION_BATTLE_USE    5
#define ITEMMENUACTION_CHECK         6
#define ITEMMENUACTION_WALK          7
#define ITEMMENUACTION_DESELECT      8
#define ITEMMENUACTION_CHECK_TAG     9
#define ITEMMENUACTION_CONFIRM      10
#define ITEMMENUACTION_SHOW         11
#define ITEMMENUACTION_GIVE_2       12
#define ITEMMENUACTION_CONFIRM_2    13
#define ITEMMENUACTION_DUMMY        14

// Exported type declarations
struct BagStruct
{
    void (*bagCallback)(void);
    u8 location;
    u8 pocket;
    u16 unk6;
    u16 cursorPosition[POCKETS_COUNT];
    u16 scrollPosition[POCKETS_COUNT];
};

extern struct BagStruct gBagPositionStruct;

struct BagMenuStruct
{
    void (*exitCallback)(void);
    u8 tilemapBuffer[0x800];
    u8 spriteId[12];
    u8 windowPointers[10];
    u8 itemOriginalLocation;
    u8 pocketSwitchDisabled:4;
    u8 itemIconSlot:2;
    u8 inhibitItemDescriptionPrint:1;
    u8 hideCloseBagText:1;
    u8 filler3[2];
    u8 pocketScrollArrowsTask;
    u8 pocketSwitchArrowsTask;
    const u8* contextMenuItemsPtr;
    u8 contextMenuItemsBuffer[4];
    u8 contextMenuNumItems;
    u8 numItemStacks[POCKETS_COUNT];
    u8 numShownItems[6];
    s16 graphicsLoadState;
    u8 filler4[0xE];
    u8 pocketNameBuffer[32][32];
    u8 filler2[4];
};

extern struct BagMenuStruct *gBagMenu;

// Exported RAM declarations

extern u16 gSpecialVar_ItemId;

// Exported ROM declarations
void CB2_GoToItemDepositMenu(void);
void FavorLadyOpenBagMenu(void);
void QuizLadyOpenBagMenu(void);
void ApprenticeOpenBagMenu(void);
void CB2_BagMenuFromBattle(void);
void SetInitialScrollAndCursorPositions(u8 pocketId);
void CB2_ReturnToBagMenuPocket(void);
void CB2_BagMenuFromStartMenu(void);
u8 GetItemListPosition(u8 pocketId);
bool8 UseRegisteredKeyItemOnField(void);
void CB2_GoToSellMenu(void);
void GoToBagMenu(u8 bagMenuType, u8 pocketId, void ( *postExitMenuMainCallback2)());
void DoWallyTutorialBagMenu(void);
void ResetBagScrollPositions(void);
void ChooseBerryForMachine(void (*exitCallback)(void));
void CB2_ChooseBerry(void);
void Task_FadeAndCloseBagMenu(u8 taskId);
void BagMenu_YesNo(u8, u8, const struct YesNoFuncTable*);
void BagMenu_InitListsMenu(u8 taskId);
void UpdatePocketItemList(u8 pocketId);
void DisplayItemMessage(u8 taskId, u8 fontId, const u8 *str, void ( *callback)(u8 taskId));
void DisplayItemMessageOnField(u8 taskId, const u8 *src, TaskFunc callback);

#endif //GUARD_item_menu_H


code:
#ifndef GUARD_ITEM_MENU_ICONS
#define GUARD_ITEM_MENU_ICONS

extern const struct CompressedSpriteSheet gBagMaleSpriteSheet;
extern const struct CompressedSpriteSheet gBagFemaleSpriteSheet;
extern const struct CompressedSpritePalette gBagPaletteTable;
extern const struct CompressedSpriteSheet gBerryCheckCircleSpriteSheet;
extern const struct CompressedSpritePalette gBerryCheckCirclePaletteTable;

void RemoveBagSprite(u8 id);
void AddBagVisualSprite(u8 bagPocketId);
void SetBagVisualPocketId(u8 bagPocketId, bool8 isSwitchingPockets);
void ShakeBagSprite(void);
void AddSwitchPocketRotatingBallSprite(s16 rotationDirection);
void AddBagItemIconSprite(u16 itemId, u8 id);
void RemoveBagItemIconSprite(u8 id);
void sub_80D4FAC(void);
void sub_80D4FC8(u8 arg0);
void sub_80D4FEC(u8 arg0);
u8 CreateBerryTagSprite(u8 id, s16 x, s16 y);
void FreeBerryTagSpritePalette(void);
u8 CreateSpinningBerrySprite(u8 berryId, u8 x, u8 y, bool8 startAffine);
u8 CreateBerryFlavorCircleSprite(s16 x);

#define TAG_BAG_GFX 100
#define TAG_ROTATING_BALL_GFX 101
#define TAG_BERRY_CHECK_CIRCLE_GFX 10000
#define TAG_BERRY_PIC_TILE 0xFFFF
#define TAG_BERRY_PIC_PAL 0x7544

#endif // GUARD_ITEM_MENU_ICONS


code:
#ifndef GUARD_ITEM_USE_H
#define GUARD_ITEM_USE_H

void ItemUseOutOfBattle_Mail(u8);
void ItemUseOutOfBattle_Bike(u8);
void ItemUseOutOfBattle_Rod(u8);
void ItemUseOutOfBattle_Itemfinder(u8);
void ItemUseOutOfBattle_PokeblockCase(u8);
void ItemUseOutOfBattle_CoinCase(u8);
void ItemUseOutOfBattle_PowderJar(u8);
void ItemUseOutOfBattle_SSTicket(u8);
void ItemUseOutOfBattle_WailmerPail(u8);
void ItemUseOutOfBattle_Medicine(u8);
void ItemUseOutOfBattle_ReduceEV(u8);
void ItemUseOutOfBattle_SacredAsh(u8);
void ItemUseOutOfBattle_PPRecovery(u8);
void ItemUseOutOfBattle_PPUp(u8);
void ItemUseOutOfBattle_RareCandy(u8);
void ItemUseOutOfBattle_TMHM(u8);
void ItemUseOutOfBattle_Repel(u8);
void ItemUseOutOfBattle_EscapeRope(u8);
void ItemUseOutOfBattle_BlackWhiteFlute(u8);
void ItemUseOutOfBattle_EvolutionStone(u8);
void ItemUseOutOfBattle_Berry(u8);
void ItemUseOutOfBattle_EnigmaBerry(u8);
void ItemUseOutOfBattle_CannotUse(u8);
void ItemUseInBattle_PokeBall(u8);
void ItemUseInBattle_StatIncrease(u8);
void ItemUseInBattle_Medicine(u8);
void ItemUseInBattle_PPRecovery(u8);
void ItemUseInBattle_Escape(u8);
void ItemUseInBattle_EnigmaBerry(u8);
void Task_UseDigEscapeRopeOnField(u8 taskId);
u8 CanUseDigOrEscapeRopeOnCurMap(void);
u8 CheckIfItemIsTMHMOrEvolutionStone(u16 itemId);

#endif // GUARD_ITEM_USE_H


code:
#ifndef GUARD_LANDMARK_H
#define GUARD_LANDMARK_H

const u8 *GetLandmarkName(u8 mapSection, u8 id, u8 count);

#endif // GUARD_LANDMARK_H


code:
#ifndef GUARD_LIBGCNMULTIBOOT_H
#define GUARD_LIBGCNMULTIBOOT_H

struct GcmbStruct
{
    u16 gcmb_field_0;
    vu8 gcmb_field_2;
    u8 filler3[0x2C - 0x3];
};

void GameCubeMultiBoot_Main(struct GcmbStruct *pStruct);
void GameCubeMultiBoot_ExecuteProgram(struct GcmbStruct *pStruct);
void GameCubeMultiBoot_Init(struct GcmbStruct *pStruct);
void GameCubeMultiBoot_HandleSerialInterrupt(struct GcmbStruct *pStruct);
void GameCubeMultiBoot_Quit(void);

#endif // GUARD_LIBGCNMULTIBOOT_H


code:
#ifndef GUARD_LIBRFU_H
#define GUARD_LIBRFU_H

#include "global.h"
#include "main.h"

#define LIBRFU_VERSION 1026

/* TODOs:
 * - documentation
 * - check if any field needs to be volatile
 * - check if field names make sense
 */

// --------------------------------------------------------------------------
//
// Restrictions When Using RFU
//
// --------------------------------------------------------------------------
/*
  The following restrictions apply when using RFU.

  <Restrictions for Direct Sound>
    (a) The timer for Sound DMA uses only 0
    (b) The prescaler for the timer count for the Sound DMA uses 59.5 ns.
    (c) The sound sampling rate is Max36.314KHz.

  <Restrictions for H-DMA or DMA started with V-Blank>
    These types of DMA can be operated on a maximum CPU cycle of 42 cycles.
    Calculate the number of the transferable DMA count based on this 42 cycles and the access cycles of the destination and source.
    For example, if both the CPU internal RAM --> VRAM have a one cycle access, then a 21 count DMA can occur.

  If RFU is used outside of these restrictions, problems, such as the loss of data caused by the failure of the AGB, as a clock slave,
  to notify that data has been received from the RFU, will occur.
  When this problem occurs, the REQ callback will send a REQ_commandID=ID_CLOCK_SLAVE_MS_CHANGE_ERROR_BY_DMA_REQ notification.
   (When using Link Manager, the LMAN call back will send a LMAN_msg=LMAN_MSG_CLOCK_SLAVE_MS_CHANGE_ERROR_BY_DMA notification.)

*/

// REQ-COMMAND (STWI) ID CODE LIST

// REQ Command ID returned by the REQ callback
#define ID_RESET_REQ                                0x0010
#define ID_LINK_STATUS_REQ                          0x0011
#define ID_VERSION_STATUS_REQ                       0x0012    // not defined in SDK header
#define ID_SYSTEM_STATUS_REQ                        0x0013
#define ID_SLOT_STATUS_REQ                          0x0014    // not defined in SDK header
#define ID_CONFIG_STATUS_REQ                        0x0015    // not defined in SDK header
#define ID_GAME_CONFIG_REQ                          0x0016
#define ID_SYSTEM_CONFIG_REQ                        0x0017
#define ID_SC_START_REQ                             0x0019
#define ID_SC_POLL_REQ                              0x001a
#define ID_SC_END_REQ                               0x001b
#define ID_SP_START_REQ                             0x001c
#define ID_SP_POLL_REQ                              0x001d
#define ID_SP_END_REQ                               0x001e
#define ID_CP_START_REQ                             0x001f
#define ID_CP_POLL_REQ                              0x0020
#define ID_CP_END_REQ                               0x0021
#define ID_DATA_TX_REQ                              0x0024
#define ID_DATA_TX_AND_CHANGE_REQ                   0x0025
#define ID_DATA_RX_REQ                              0x0026
#define ID_MS_CHANGE_REQ                            0x0027    // When returned by the REQ callback, this ID indicates that execution of rfu_REQ_changeMasterSlave has finished.
                                                              // This ID is returned by both the REQ callback and the MSC callback.
                                                              // When returned by the MSC callback, this is notification that after the AGB has been made into the clock slave, the MC_Timer expired and the RFU returned the AGB to be the clock master.
#define ID_DISCONNECT_REQ                           0x0030
#define ID_TEST_MODE_REQ                            0x0031    // not defined in SDK header
#define ID_CPR_START_REQ                            0x0032
#define ID_CPR_POLL_REQ                             0x0033
#define ID_CPR_END_REQ                              0x0034
#define ID_UNK35_REQ                                0x0035    // not defined in SDK header
#define ID_UNK36_REQ                                0x0036    // not defined in SDK header
#define ID_RESUME_RETRANSMIT_AND_CHANGE_REQ         0x0037
#define ID_STOP_MODE_REQ                            0x003d
#define ID_CLOCK_SLAVE_MS_CHANGE_ERROR_BY_DMA_REQ   0x00ff    // When the AGB is the clock slave, the RFU generates an informational notice, and an automatically started DMA, such as HDMA, is generated at the instant the AGB is being returned as the clock master. This ID is notified by a REQ callback when the exchange of this information (REQ command) fails.

// REQ Command ID returned by the MSC callback
#define ID_DISCONNECTED_AND_CHANGE_REQ              0x0029
#define ID_DATA_READY_AND_CHANGE_REQ                0x0028
#define ID_DRAC_REQ_WITH_ACK_FLAG                   0x0128

// --------------------------------------------------------------------------
//
// Data Definitions
//
// --------------------------------------------------------------------------

#define RFU_ID                          0x00008001         // ID number of AGB-RFU device: ID returned by execution of rfu_REQBN_softReset_and_checkID.

#define RFU_MBOOT_DOWNLOADER_SERIAL_NO  0x0000             // The game serial number of the multi-boot downloader (programs that boot without a Game Pak)

#define RFU_API_BUFF_SIZE_RAM           0x0e64             // Necessary size for buffer specified by rfu_initializeAPI (fast communication version that operates the library SIO interrupt routines in RAM)
#define RFU_API_BUFF_SIZE_ROM           0x0504             // Necessary size for buffer specified by rfu_initializeAPI (fast communication version that operates the library SIO interrupt routines in ROM)

#define RFU_CHILD_MAX                   4                  // Maximum number of slaves that can be connected to one parent device

#define RFU_GAME_NAME_LENGTH            13                 // Possible length of game name set by rfu_REQB_configGameData
#define RFU_USER_NAME_LENGTH            8                  // Possible length of user name set by rfu_REQB_configGameData

#define RFU_H_DMA_MAX_CPU_CYCLE         42                 // Maximum number of CPU cycles for H-DMA or DMA that starts with V-Blank that can operate when using RFU

// Value to determine the level of the icon that displays the link strength of the wireless status (value of rfuLinkStatus->strength[0-3])
#define RFU_LINK_ICON_LEVEL4_MAX        255                // 90% -100%  (If the value is betwen 229 and 255, the icon level is 4)
#define RFU_LINK_ICON_LEVEL4_MIN        229
#define RFU_LINK_ICON_LEVEL3_MAX        228                // 50% - 89%  (If the value is betwen 127 and 228, the icon level is 3)
#define RFU_LINK_ICON_LEVEL3_MIN        127
#define RFU_LINK_ICON_LEVEL2_MAX        126                // 10% - 49%  (If the value is betwen 25 and 126, the icon level is 2)
#define RFU_LINK_ICON_LEVEL2_MIN         25
#define RFU_LINK_ICON_LEVEL1_MAX         24                //  0% -  9%  (If the value is betwen 0 and 24, the icon level is 1)
#define RFU_LINK_ICON_LEVEL1_MIN          0

// *******************************************************
// Definition Data for Arguments Used in Library Functions
// *******************************************************
// Specified by u16 mbootFlag in rfu_REQ_configGameData
#define RFU_MBOOT_FLAG                  0x01               // Enabling this flag, allows connection to a multi-boot program.

// AvailSlot (number of slots available for connection) used in u16 availSlotFlag in rfu_REQ_configSystem
#define AVAIL_SLOT4                     0x0000
#define AVAIL_SLOT3                     0x0001
#define AVAIL_SLOT2                     0x0002
#define AVAIL_SLOT1                     0x0003

// u8 connTypeFlag specified by rfu_setRecvBuffer
#define TYPE_UNI                        0x10               // UNI-type
#define TYPE_NI                         0x20               // NI-type

// u8 connTypeFlag specified by rfu_clearSlot
#define TYPE_UNI_SEND                   0x01               // UNI-type send
#define TYPE_UNI_RECV                   0x02               // UNI-type receive
#define TYPE_NI_SEND                    0x04               // NI-type send
#define TYPE_NI_RECV                    0x08               // NI-type receive

// *******************************************************
// Definition Data Returned by Return Values for Library Functions
// *******************************************************

// The function doesn't have return value.
// Value of u8 *status for rfu_REQ_pollConnectParent (Connection Trial Status)
// #define CP_STATUS_DONE                  0x00               // Connection successful
// #define CP_STATUS_IN_PROCESS            0x01               // Connecting
// #define CP_STATUS_SLOT_CLOSED           0x02               // Parent device is not in connection mode with child device
// #define CP_STATUS_DISCONNECTED          0x03               // Disconnected by parent device while connecting
// #define CP_STATUS_UNKNOWN               0xff               // Cannot read status due to REQ-API execution error

// The function doesn't exist.
// Value of u8 *status argument for rfu_REQ_pollRecoveryConnect (Link Restore Status)
// #define RC_STATUS_DONE                  0x00               // Connection restore successful
// #define RC_STATUS_FAILED                0x01               // Connection restore failure (meaningless to try anymore)
// #define RC_STATUS_SEARCHING_PARENT      0x02               // Searching for parent device
// #define RC_STATUS_UNKNOWN               0xff               // Cannot read status due to REQ-API execution error

// Value of u8 *linkLossReason argument for rfu_REQBN_watchLink (Reason for Link Loss)
#define REASON_DISCONNECTED             0x00               // State of complete disconnection with rfuLL_disconnect and no possibility of restoring the link (can detect only child device)
#define REASON_LINK_LOSS                0x01               // State of link loss that allows for the possibility for the link to be restored

// *******************************************************
// Definition Data Returned with Return Values for Library Functions
// *******************************************************

// Value returned by rfu_getMasterSlave
#define AGB_CLK_SLAVE                   0                  // AGB clock slave
#define AGB_CLK_MASTER                  1                  // AGB clock master

// *******************************************************
// Error Code Group for Library Functions
// *******************************************************

// Error codes returned by u16 REQ_result with a REQ callback when a REQ-API function is executed
#define ERR_REQ_CMD                     0x0000
#define ERR_REQ_CMD_CLOCK_DRIFT        (ERR_REQ_CMD | 0x0001) // Clock drift occurs when a REQ command is sent
#define ERR_REQ_CMD_SENDING            (ERR_REQ_CMD | 0x0002) // The next command cannot be issued because a REQ command is being sent
#define ERR_REQ_CMD_ACK_REJECTION      (ERR_REQ_CMD | 0x0003) // The REQ command was refused when issued
#define ERR_REQ_CMD_CLOCK_SLAVE        (ERR_REQ_CMD | 0x0004) // Issuing the REQ command was attempted but failed because the AGB is the clock slave
#define ERR_REQ_CMD_IME_DISABLE        (ERR_REQ_CMD | 0x0006) // Issuing the REQ command was attempted but failed because the IME register is 0

#define ERR_PID_NOT_FOUND               0x0100                // The specified PID does not exist in the gRfuLinkStatus->partner[0-3].id list

// Error code returned by the return value of rfu_initializeAPI
#define ERR_RFU_API_BUFF_SIZE           0x0001
#define ERR_RFU_API_BUFF_ADR            0x0002

// Error codes returned by return values for rfu_REQBN_softReset_and_checkID
#define ERR_ID_CHECK_IME_DISABLE        0xffffffff            // ID check could not be executed because REG_IME=0 when executing rfu_REQBN_softReset_and_checkID

// Error codes returned by rfu_getConnectParentStatus and rfu_CHILD_getConnectRecoveryStatus
#define ERR_REQ_CMD_ID                 (ERR_REQ_CMD | 0x0010) // A required REQ command was not executed within this function execution

// Error codes returned by rfu_NI_setSendData, rfu_UNI_setSendData, and rfu_NI_CHILD_setSendGameName
#define ERR_MODE                        0x0300
#define ERR_MODE_NOT_PARENT            (ERR_MODE | 0x0000)    // not in SDK
#define ERR_MODE_NOT_CONNECTED         (ERR_MODE | 0x0001)    // RFU is not in connection mode (parent or child)

#define ERR_SLOT                        0x0400
#define ERR_SLOT_NO                    (ERR_SLOT | 0x0000)    // The specified slot number is not right
#define ERR_SLOT_NOT_CONNECTED         (ERR_SLOT | 0x0001)    // The specified slot is not connected
#define ERR_SLOT_BUSY                  (ERR_SLOT | 0x0002)    // The specified slot is already communicating
#define ERR_SLOT_NOT_SENDING           (ERR_SLOT | 0x0003)    // The specified slot is not currently sending (Note: This is returned by rfu_UNI_re_setSendData)
#define ERR_SLOT_TARGET                (ERR_SLOT | 0x0004)    // The specified target slot is not right

#define ERR_SUBFRAME_SIZE               0x0500                // The specified subframe size is either larger than the remaining communication frame size or smaller than the link layer subframe header size

// Error code returned by rfu_clearSlot, rfu_setRecvBuffer, and rfu_changeSendTarget
#define ERR_COMM_TYPE                   0x0600                // The specified communication format is not right

// Error code returned by rfu_REQ_recvData (when receiving NI-type or UNI-type data)
#define ERR_DATA_RECV                   0x0700                // Error notification is issued in the following format.
                                                              // "ERR_DATA_RECV | (slot number issuing error with 0x0010<<UNI) | (slot number issuing error with 0x0001<<NI)"
                                                              // The actual error code is stored in gRfuSlotStatusNI or gRfuSlotStatusUNI[x]->recv.errorCode.

// Error code during NI-type communication (code entered into gRfuSlotStatusNI[x]->recv.errorCode)
#define ERR_RECV_BUFF_OVER              (ERR_DATA_RECV | 0x0001)  // The receive data size is larger than the receive buffer (Note: This error is used for both NI and UNI)
#define ERR_RECV_REPLY_SUBFRAME_SIZE    (ERR_DATA_RECV | 0x0002)  // All frames are already in use by other communications, and a subframe for reception response could not be secured

// Error code during UNI-type communication (code entered into gRfuSlotStatusUNI[x]->recv.errorCode)
#define ERR_RECV_DATA_OVERWRITED        (ERR_DATA_RECV | 0x0008)  // Received new data when gRfuSlotStatusUNI[x]->recv.newDataFlag=1

// not in SDK header
#define ERR_RECV_UNK                    (ERR_DATA_RECV | 0x0001 | 0x0008)

// *******************************************************
// Definition Data Used by Global Variables in the Library
// *******************************************************

// gRfuLinkStatus-------------------------------------------
// Connection status (refer to gRfuLinkStatus->parentChild)
#define MODE_NEUTRAL                    0xff               // Initialization
#define MODE_CHILD                      0x00               // Child
#define MODE_PARENT                     0x01               // Parent

// gRfuSlotStatusNI,UNI-----------------------------------
// Definition data for NI-(Numbered Information) and UNI-(Un-Numbered Information) type communication

// Definition data common to NI- and UNI-type communication
#define LLF_P_SIZE                      87                 // Maximum link layer communication frame size for the Parent (Maximum number of bytes per transmission)
#define LLF_C_SIZE                      16                 //      "                                "     for the Child
#define LLSF_P_HEADER_SIZE              3                  // Header size used by one link layer subframe (NI or UNI frame) for the Parent
#define LLSF_C_HEADER_SIZE              2                  //      "                                "                       for the Child

// Link Layer Communication Code
#define LCOM_NULL                       0x0000
#define LCOM_NI_START                   0x0001
#define LCOM_NI                         0x0002
#define LCOM_NI_END                     0x0003
#define LCOM_UNI                        0x0004

// Flag for Slot Status Data
#define SLOT_BUSY_FLAG                  0x8000             // Slot in use
#define SLOT_SEND_FLAG                  0x0020             // Send
#define SLOT_RECV_FLAG                  0x0040             // Receive

// NI- and UNI-type shared slot stand-by data (same state as gRfuSlotStatusNI[x]->send or ->recv.state or gRfuSlotStatusUNI)
#define SLOT_STATE_READY                0x0000             // Slot initialization

// Status data for NI-type communication (gRfuSlotStatusNI[x]->send or ->recv.state)
#define SLOT_STATE_SEND_START           (SLOT_BUSY_FLAG | SLOT_SEND_FLAG | LCOM_NI_START)   // Start transmission
#define SLOT_STATE_SENDING              (SLOT_BUSY_FLAG | SLOT_SEND_FLAG | LCOM_NI)         // Transmitting
#define SLOT_STATE_SEND_LAST            (SLOT_BUSY_FLAG | SLOT_SEND_FLAG | LCOM_NI_END)     // Verify transmission end
#define SLOT_STATE_SEND_NULL            (SLOT_BUSY_FLAG | SLOT_SEND_FLAG | LCOM_NULL)       // Send NULL subframe to notify end of transmission
#define SLOT_STATE_SEND_SUCCESS         (                 SLOT_SEND_FLAG | 0x006)           // Transmission successful
#define SLOT_STATE_SEND_FAILED          (                 SLOT_SEND_FLAG | 0x007)           // Transmission failed
                                                                                // Distinction of slot where transmission succeeded/failed compares gRfuSlotStatusNI[x]->send.bmSlot and same bmSlot_org
#define SLOT_STATE_RECV_START           (SLOT_BUSY_FLAG | SLOT_RECV_FLAG | LCOM_NI_START)   // Start reception
#define SLOT_STATE_RECEIVING            (SLOT_BUSY_FLAG | SLOT_RECV_FLAG | LCOM_NI)         // Receiving
#define SLOT_STATE_RECV_LAST            (SLOT_BUSY_FLAG | SLOT_RECV_FLAG | LCOM_NI_END)     // Verify reception end
#define SLOT_STATE_RECV_SUCCESS         (                 SLOT_RECV_FLAG | 0x006)           // Reception successful
#define SLOT_STATE_RECV_FAILED          (                 SLOT_RECV_FLAG | 0x007)           // Reception failed
#define SLOT_STATE_RECV_SUCCESS_AND_SENDSIDE_UNKNOWN     (SLOT_RECV_FLAG | 0x008)           // The data was received successful, but because the end of the communication was incomplete, whether the transmission side status is successful or failed is unknown
#define SLOT_STATE_RECV_IGNORE          (                 SLOT_RECV_FLAG | 0x009)           // Ignore reception (refer to gRfuSlotStatusNI[x]->recv.errorCode for reason for ignoring)

// Status data for UNI-type communication (refer to gRfuSlotStatusUNI[x]->send.state)
#define SLOT_STATE_SEND_UNI             (SLOT_BUSY_FLAG | SLOT_SEND_FLAG | LCOM_UNI)        // Transmitting

// the following structs are not documented in SDK
struct RfuPacket8
{
    u8 data[0x74];
};

struct RfuPacket32
{
    u32 command;
    u32 data[0x1C];
};

union RfuPacket
{
    struct RfuPacket32 rfuPacket32;
    struct RfuPacket8 rfuPacket8;
};

struct STWIStatus
{
    vs32 state;
    u8 reqLength;
    u8 reqNext;
    u8 reqActiveCommand;
    u8 ackLength;
    u8 ackNext;
    u8 ackActiveCommand;
    u8 timerSelect;
    u8 unk_b;
#if LIBRFU_VERSION >= 1026
    s32 timerState;
#else
    u32 timerState;
#endif
    vu8 timerActive;
    u8 unk_11;
    vu16 error;
    vu8 msMode;
    u8 recoveryCount;
    u8 unk_16;
    u8 unk_17;
    void (*callbackM)();
    void (*callbackS)(u16);
    void (*callbackID)(void);
    union RfuPacket *txPacket;
    union RfuPacket *rxPacket;
    vu8 sending;
};

// This struct is used as u8 array in SDK.
struct RfuIntrStruct
{
    union RfuPacket rxPacketAlloc;
    union RfuPacket txPacketAlloc;
    u8 block1[0x960]; // size of librfu_intr.s binary
    struct STWIStatus block2;
};

// Data Structure for Transmitting UNI-Type Data
struct UNISend
{
    u16 state;         // Slot communication state (SLOT_STATE_READY, SLOT_STATE_SEND_UNI)
    u8 dataReadyFlag;  // Flag indicating transmission data is prepared (0: data sent; 1: transmission data ready)
                       //   Set with rfu_UNI_re_setSendData or rfu_UNI_readySendData, cleared when data is sent with rfu_REQ_sendData.
    u8 bmSlot;         // Expresses transmission destination slot as bits
    u16 payloadSize;   // Payload size of 1 transmission. "size" specified by rfu_UNI_setSendData or rfu_UNI_re_setSendData is used.
    const void *src;   // Beginning address of transmission data
};

// Data Structure for Receiving UNI Data
struct UNIRecv
{
    u16 state;         // Slot communication state (SLOT_STATE_READY, SLOT_STATE_RECEIVING, SLOT_STATE_RECV_IGNORE)
    u16 errorCode;     // Error code during reception
    u16 dataSize;      // Size of receive data
    u8 newDataFlag;    // Flag indicating whether receive data has newly arrived (0: no newly arrived data; 1: newly arrived data)
                       //   The flag is cleared with rfu_UNI_clearRecvNewDataFlag; it is set when data is received with rfu_REQ_recvData.
    u8 dataBlockFlag;  // Flag for unreferenced receive data overwrite block (default is 0 Note: not used)
};

// Slot Status Data Structure for UNI-Type Communication
struct RfuSlotStatusUNI
{
    struct UNISend send;    // Transmission Status
    struct UNIRecv recv;    // Reception Status
    void *recvBuffer;       // Reception Buffer Address
    u32 recvBufferSize;     // Reception Buffer Size
};

#define WINDOW_COUNT    4

struct NIComm
{
    u16 state;                     // Communication state of slot
    u16 failCounter;               // Count of failed transmissions/receptions (Count is increased when transmission/reception of data does not succeed within 1PF=16.7 ms)
    const u8 *now_p[WINDOW_COUNT]; // Address of current send/receive (The data is divided into WINDOW_COUNT blocks and sent in payloadSize units.)
    u32 remainSize;                // Size of remaining communication data
    u16 errorCode;                 // Error code
    u8 bmSlot;                     // Expresses the current communication slot in bits
                                   //   (When sending from the Master, because multiple slaves can be specified with bmSlot, communications are terminated based on the failCounter for each child device)
    // Parameters used inside the Library
    u8 recvAckFlag[WINDOW_COUNT];
    u8 ack;
    u8 phase;
    u8 n[WINDOW_COUNT];
    // Parameters indicating the current communication content
    const void *src;               // Start address transmission data (valid only for transmitting device)
    u8 bmSlotOrg;                  // Expresses the communication source slot at the beginning of the transmission in bits (valid only for transmitting device)
    u8 dataType;                   // Transmission/reception data type (0: User data; 1: Game identification information)
    u16 payloadSize;               // Payload size for one transmission
    u32 dataSize;                  // Size of transmission/reception data
                                   //   Calculated by subtracting link layer header size from subFrameSize specified by the rfu_NI_setSendData function
};

struct RfuSlotStatusNI
{
    struct NIComm send;              // Transmission Status
    struct NIComm recv;              // Reception Status
    void *recvBuffer;                // Reception Buffer Address
    u32 recvBufferSize;              // Reception Buffer Size
};

// Game Identification Information Data Structure
struct RfuTgtData
{
    u16 id;                                    // ID of parent candidate                                 ID of connection partner
    u8  slot;                                  // Slot number where parent candidate can enter           Connection slot number
    u8  mbootFlag;                             // Flag to indicate whether or not the parent candidate   Flag to indicate whether or not the connection partner
                                               //   is multiboot program for download                      is multiboot program for download
    u16 serialNo;                              // Game serial number of parent candidate                 Game serial number of connection partner
    u8  gname[RFU_GAME_NAME_LENGTH + 2];       // Game name of parent candidate                          Game name of connection partner
    u8  uname[RFU_USER_NAME_LENGTH + 1];       // User name for parent candidate                         User name for connection partner
};

struct RfuLinkStatus
{
    u8  parentChild;                            // Connection status (0x01:MODE_PARENT  0x00:MODE_CHILD  0xff:MODE_NEUTRAL)
    u8  connCount;                              // Number of connections
    u8  connSlotFlag;                           // Flag to indicate in bits the connection slot (0x01<<Connection slot number)
    u8  linkLossSlotFlag;                       // Flag to indicate in bits the slot where the link loss was generated (")
    u8  sendSlotNIFlag;                         // Flag to indicate in bits the slot where NI-type send is occurring (")
    u8  recvSlotNIFlag;                         // Flag to indicate in bits the slot where NI-type receive is occurring (")
    u8  sendSlotUNIFlag;                        // Flag to indicate in bits the slot where UNI-type send is occurring (")
    u8  getNameFlag;                            // Parent: Flag to indicate whether or not game identification information was obtained from the child connected to this slot (")
                                                // Child: Flag to indicate whether or not game identification information was sent to the parent connected to this slot (")
    u8  findParentCount;                        // Number of parent candidates discovered with rfu_REQ_xxxSearchParent, valid only with a child device
    u8  watchInterval;                          // Link monitor execution interval (16.7 ms unit AGB picture frame)
    u8  strength[RFU_CHILD_MAX];                // Link strength value (0x00 - 0xff; 0x00 is link loss. Updates with rfu_REQBN_watchLink)
    vu8 LLFReadyFlag;                           // Indicates whether the link layer frame to send next has be constructed (Flag is on when calling rfu_constructLLFrame, flag is cleared when sending by rfu_REQ_sendData.)
    u8  remainLLFrameSizeParent;                // Remaining size of the link layer communication frame for the parent device
    u8  remainLLFrameSizeChild[RFU_CHILD_MAX];  // Remaining size of the link layer communication frame for each slot for child device
    struct RfuTgtData partner[RFU_CHILD_MAX];   // Parent, Child: When there is a connection, the matrix element corresponding to the number of the connected slot
                                                //   stores the game identification information for the connection partner.
                                                // Child: Stores the game identification information for the parent candidate discovered when executing rfu_REQ_xxxxSearchParent.
    struct RfuTgtData my;                       // The device's own game identification information (unrelated to the element slot value)
};

// the following structs are not documented in SDK
struct RfuFixed
{
    void (*reqCallback)(u16, u16);
    void (*fastCopyPtr)(const u8 **, u8 **, s32);
    u16 fastCopyBuffer[24];
    u32 fastCopyBuffer2[12];
    u32 LLFBuffer[29];
    struct RfuIntrStruct *STWIBuffer;
};

struct RfuStatic
{
    u8 flags;
    u8 NIEndRecvFlag;
    u8 recvRenewalFlag;
    u8 commExistFlag;
    u8 recvErrorFlag;
    u8 recoveryBmSlot;
    u8 nowWatchInterval;
    u8 nullFrameCount;
    u8 emberCount;
    u8 SCStartFlag;
    u8 linkEmergencyFlag[RFU_CHILD_MAX];
    u8 lsFixedCount[RFU_CHILD_MAX];
    u16 cidBak[RFU_CHILD_MAX];
    u16 linkEmergencyLimit;
    u16 reqResult;
    u16 tryPid;
    u16 watchdogTimer;
    u32 totalPacketSize;
};

extern struct STWIStatus *gSTWIStatus;
extern struct RfuLinkStatus *gRfuLinkStatus;
extern struct RfuStatic *gRfuStatic;
extern struct RfuFixed *gRfuFixed;
extern struct RfuSlotStatusNI *gRfuSlotStatusNI[RFU_CHILD_MAX];
extern struct RfuSlotStatusUNI *gRfuSlotStatusUNI[RFU_CHILD_MAX];

// librfu_sio32id
s32 AgbRFU_checkID(u8 maxTries);

// Arguments with "bm..." specify slots of the form (0x01 << slot number) that are the object of a function operation.

// librfu_rfu
// API Initialization and Initial Settings
    // API Initialization
u16 rfu_initializeAPI(u32 *APIBuffer, u16 buffByteSize, IntrFunc *sioIntrTable_p, bool8 copyInterruptToRam);
    // Set Timer Interrupt
void rfu_setTimerInterrupt(u8 timerNo, IntrFunc *timerIntrTable_p);
    // Resident Function called from within a V-Blank Interrupt
u16 rfu_syncVBlank(void);
    // Specify REQ Callback function
void rfu_setREQCallback(void (*callback)(u16 reqCommandId, u16 reqResult));
    // REQ-API Execution Completion Wait
u16 rfu_waitREQComplete(void);

// RFU Initialization and Initial Settings
    // RFU Startup and ID Check (Forced RFU reset occurs simultaneously)
u32 rfu_REQBN_softReset_and_checkID(void);
    // RFU Reset
void rfu_REQ_reset(void);
    // Set RFU to Stop Mode (Power Down)
void rfu_REQ_stopMode(void);
    // RFU Hardware Settings
void rfu_REQ_configSystem(u16 availSlotFlag, u8 maxMFrame, u8 mcTimer);
    // Game Identification Information Configuration
void rfu_REQ_configGameData(u8 mbootFlag, u16 serialNo, const u8 *gname, const u8 *uname);

// RFU Connection Process
    // Operate as parent device; search for and connect to child device
void rfu_REQ_startSearchChild(void);
void rfu_REQ_pollSearchChild(void);
void rfu_REQ_endSearchChild(void);
    // Operate as child device; search for parent device
void rfu_REQ_startSearchParent(void);
void rfu_REQ_pollSearchParent(void);
void rfu_REQ_endSearchParent(void);
    // Operate as child device; connect to specified parent device
void rfu_REQ_startConnectParent(u16 pid);
void rfu_REQ_pollConnectParent(void);
void rfu_REQ_endConnectParent(void);
u16 rfu_getConnectParentStatus(u8 *status,u8 *connectSlotNo);
    // Restore link from child device
void rfu_REQ_CHILD_startConnectRecovery(u8 bmRecoverySlot);
void rfu_REQ_CHILD_pollConnectRecovery(void);
void rfu_REQ_CHILD_endConnectRecovery(void);
u16 rfu_CHILD_getConnectRecoveryStatus(u8 *status);

// RFU Link Management
    // Link Monitoring
u16 rfu_REQBN_watchLink(u16 reqCommandId, u8 *bmLinkLossSlot, u8 *linkLossReason, u8 *parentBmLinkRecoverySlot);
    // Link Disconnect
void rfu_REQ_disconnect(u8 bmDisconnectSlot);

// Relation of clock between AGB and RFU
    // Switch to AGB clock slave
void rfu_REQ_changeMasterSlave(void);
    // Acquire either the master or slave clock from the current AGB-RFU
bool8 rfu_getMasterSlave(void);

// Communication Configuration
    // MSC Callback Configuration
void rfu_setMSCCallback(void (*callback)(u16 reqCommandId));
    // Shared by NI- and UNI-type communications
        // Clear Communication Status
void rfu_clearAllSlot(void);
u16 rfu_clearSlot(u8 connTypeFlag, u8 slotStatusIndex);
        // Set Receive Buffer
u16 rfu_setRecvBuffer(u8 connType, u8 slotNo, void *buffer, u32 buffSize);

// Receive/Send Data
    // UNI-type communication
        // Set transmission data
u16 rfu_UNI_setSendData(u8 bmSendSlot, const void *src, u8 size);
        // Enable transmission data
void rfu_UNI_readySendData(u8 slotStatusIndex);
        // Change address or size of transmission data and enable transmission data
u16 rfu_UNI_changeAndReadySendData(u8 slotStatusIndex, const void *src, u8 size);
        // Used only by parent device. At the beginning of a MSC Callback that received notification that the data transmission completed, an ACK flag is obtained.
u16 rfu_UNI_PARENT_getDRAC_ACK(u8 *ackFlag);
        // Clear the flag that indicates newly arrived reception data
void rfu_UNI_clearRecvNewDataFlag(u8 slotStatusIndex);
    // NI-type Communication
        // Set transmission data
u16 rfu_NI_setSendData(u8 bmSendSlot, u8 subFrameSize, const void *src, u32 size);
        // Used only by child device. After establishing connection at the RFU level, configure transmission of child device game identification information in order to authenticate connection
u16 rfu_NI_CHILD_setSendGameName(u8 slotNo, u8 subFrameSize);
        // Stop the NI data currently being received
u16 rfu_NI_stopReceivingData(u8 slotStatusIndex);
    // Shared by NI- and UNI-type communications
        // Narrow transmission targets for transmission data.
u16 rfu_changeSendTarget(u8 connType, u8 slotStatusIndex, u8 bmNewTgtSlot);

    // Functions for sending/receiving data to RFU
        // Data transmission
void rfu_REQ_sendData(bool8 clockChangeFlag);
        // Used only by parent device. Resend previous sent data (packet)
void rfu_REQ_PARENT_resumeRetransmitAndChange(void);
        // Read receive data
void rfu_REQ_recvData(void);

// For Multi-boot
    // Inherits the information about the link established by the downloader just after the program downloaded with multiboot starts up.
u16 rfu_MBOOT_CHILD_inheritanceLinkStatus(void);

// For Debug
    // Obtain address of the SWTI-layer receive buffer
u8 *rfu_getSTWIRecvBuffer(void);
    // Obtain RFU state
void rfu_REQ_RFUStatus(void);
u16 rfu_getRFUStatus(u8 *rfuState);
    // Using RFU, generate noise (jamming radio waves) for other RFUs
void rfu_REQ_noise(void);

// librfu_intr
void IntrSIO32(void);

// librfu_stwi
void STWI_init_all(struct RfuIntrStruct *interruptStruct, IntrFunc *interrupt, bool8 copyInterruptToRam);
void STWI_set_MS_mode(u8 mode);
void STWI_init_Callback_M(void);
void STWI_init_Callback_S(void);
void STWI_set_Callback_M(void *callbackM);
void STWI_set_Callback_S(void (*callbackS)(u16));
void STWI_init_timer(IntrFunc *interrupt, s32 timerSelect);
void AgbRFU_SoftReset(void);
void STWI_set_Callback_ID(void (*func)(void));
u16 STWI_read_status(u8 index);
u16 STWI_poll_CommandEnd(void);
void STWI_send_DataRxREQ(void);
void STWI_send_MS_ChangeREQ(void);
void STWI_send_StopModeREQ(void);
void STWI_send_SystemStatusREQ(void);
void STWI_send_GameConfigREQ(const u8 *serial_uname, const u8 *gname);
void STWI_send_ResetREQ(void);
void STWI_send_LinkStatusREQ(void);
void STWI_send_VersionStatusREQ(void);
void STWI_send_SlotStatusREQ(void);
void STWI_send_ConfigStatusREQ(void);
void STWI_send_ResumeRetransmitAndChangeREQ(void);
void STWI_send_SystemConfigREQ(u16 availSlotFlag, u8 maxMFrame, u8 mcTimer);
void STWI_send_SC_StartREQ(void);
void STWI_send_SC_PollingREQ(void);
void STWI_send_SC_EndREQ(void);
void STWI_send_SP_StartREQ(void);
void STWI_send_SP_PollingREQ(void);
void STWI_send_SP_EndREQ(void);
void STWI_send_CP_StartREQ(u16 unk1);
void STWI_send_CP_PollingREQ(void);
void STWI_send_CP_EndREQ(void);
void STWI_send_DataTxREQ(const void *in, u8 size);
void STWI_send_DataTxAndChangeREQ(const void *in, u8 size);
void STWI_send_DataReadyAndChangeREQ(u8 unk);
void STWI_send_DisconnectedAndChangeREQ(u8 unk0, u8 unk1);
void STWI_send_DisconnectREQ(u8 unk);
void STWI_send_TestModeREQ(u8 unk0, u8 unk1);
void STWI_send_CPR_StartREQ(u16 unk0, u16 unk1, u8 unk2);
void STWI_send_CPR_PollingREQ(void);
void STWI_send_CPR_EndREQ(void);

#endif // GUARD_LIBRFU_H


code:
#ifndef GUARD_LILYCOVE_LADY_H
#define GUARD_LILYCOVE_LADY_H

u8 GetLilycoveLadyId(void);
void InitLilycoveLady(void);
void ResetLilycoveLadyForRecordMix(void);
void FieldCallback_FavorLadyEnableScriptContexts(void);
void FieldCallback_QuizLadyEnableScriptContexts(void);
void QuizLadyClearQuestionForRecordMix(const LilycoveLady *lilycoveLady);
bool8 GivePokeblockToContestLady(struct Pokeblock *pokeblock);
void BufferContestLadyMonName(u8 *dest1, u8 *dest2);
void BufferContestLadyPlayerName(u8 *dest);
void BufferContestLadyLanguage(u8 *dest);
void BufferContestName(u8 *dest, u8 category);
u8 sub_818E880(void);

#endif //GUARD_LILYCOVE_LADY_H


code:
#ifndef GUARD_LINK_H
#define GUARD_LINK_H

#define MAX_LINK_PLAYERS 4
#define MAX_RFU_PLAYERS 5
#define CMD_LENGTH 8
#define QUEUE_CAPACITY 50
#define BLOCK_BUFFER_SIZE 0x100

#define LINK_SLAVE 0
#define LINK_MASTER 8

#define LINK_STAT_LOCAL_ID               0x00000003
#define LINK_STAT_PLAYER_COUNT           0x0000001C
#define LINK_STAT_PLAYER_COUNT_SHIFT     2
#define LINK_STAT_MASTER                 0x00000020
#define LINK_STAT_MASTER_SHIFT           5
#define LINK_STAT_CONN_ESTABLISHED       0x00000040
#define LINK_STAT_CONN_ESTABLISHED_SHIFT 6
#define LINK_STAT_RECEIVED_NOTHING       0x00000100
#define LINK_STAT_RECEIVED_NOTHING_SHIFT 8
#define LINK_STAT_UNK_FLAG_9             0x00000200
#define LINK_STAT_UNK_FLAG_9_SHIFT       9
#define LINK_STAT_ERRORS                 0x0007F000
#define LINK_STAT_ERRORS_SHIFT           12

#define LINK_STAT_ERROR_HARDWARE         0x00001000
#define LINK_STAT_ERROR_HARDWARE_SHIFT   12
#define LINK_STAT_ERROR_CHECKSUM         0x00002000
#define LINK_STAT_ERROR_CHECKSUM_SHIFT   13
#define LINK_STAT_ERROR_QUEUE_FULL       0x00004000
#define LINK_STAT_ERROR_QUEUE_FULL_SHIFT 14
#define LINK_STAT_ERROR_LAG_MASTER       0x00010000
#define LINK_STAT_ERROR_LAG_MASTER_SHIFT 16
#define LINK_STAT_ERROR_INVALID_ID       0x00020000
#define LINK_STAT_ERROR_INVALID_ID_SHIFT 17
#define LINK_STAT_ERROR_LAG_SLAVE        0x00040000
#define LINK_STAT_ERROR_LAG_SLAVE_SHIFT  18

#define EXTRACT_PLAYER_COUNT(status) \
(((status) & LINK_STAT_PLAYER_COUNT) >> LINK_STAT_PLAYER_COUNT_SHIFT)
#define EXTRACT_MASTER(status) \
(((status) >> LINK_STAT_MASTER_SHIFT) & 1)
#define EXTRACT_CONN_ESTABLISHED(status) \
(((status) >> LINK_STAT_CONN_ESTABLISHED_SHIFT) & 1)
#define EXTRACT_RECEIVED_NOTHING(status) \
(((status) >> LINK_STAT_RECEIVED_NOTHING_SHIFT) & 1)
#define EXTRACT_LINK_ERRORS(status) \
(((status) & LINK_STAT_ERRORS) >> LINK_STAT_ERRORS_SHIFT)

#define LINKCMD_BLENDER_STOP            0x1111
#define LINKCMD_SEND_LINK_TYPE          0x2222
#define LINKCMD_BLENDER_SCORE_MISS      0x2345
#define LINKCMD_READY_EXIT_STANDBY      0x2FFE
#define LINKCMD_SEND_PACKET             0x2FFF
#define LINKCMD_BLENDER_SEND_KEYS       0x4444
#define LINKCMD_BLENDER_SCORE_BEST      0x4523
#define LINKCMD_BLENDER_SCORE_GOOD      0x5432
#define LINKCMD_0x5555                  0x5555
#define LINKCMD_0x5566                  0x5566
#define LINKCMD_READY_CLOSE_LINK        0x5FFF
#define LINKCMD_0x6666                  0x6666
#define LINKCMD_0x7777                  0x7777
#define LINKCMD_BLENDER_PLAY_AGAIN      0x7779
#define LINKCMD_0x7FFF                  0x7FFF
#define LINKCMD_CONT_BLOCK              0x8888
#define LINKCMD_BLENDER_NO_BERRIES      0x9999
#define LINKCMD_BLENDER_NO_PBLOCK_SPACE 0xAAAA
#define LINKCMD_0xAAAB                  0xAAAB
#define LINKCMD_READY_TO_TRADE          0xAABB
#define LINKCMD_READY_FINISH_TRADE      0xABCD
#define LINKCMD_INIT_BLOCK              0xBBBB
#define LINKCMD_READY_CANCEL_TRADE      0xBBCC
#define LINKCMD_SEND_HELD_KEYS          0xCAFE
#define LINKCMD_SEND_BLOCK_REQ          0xCCCC
#define LINKCMD_START_TRADE             0xCCDD
#define LINKCMD_CONFIRM_FINISH_TRADE    0xDCBA
#define LINKCMD_SET_MONS_TO_TRADE       0xDDDD
#define LINKCMD_0xDDEE                  0xDDEE
#define LINKCMD_REQUEST_CANCEL          0xEEAA
#define LINKCMD_CANCEL_TRADE            0xEEBB
#define LINKCMD_0xEECC                  0xEECC

#define LINKTYPE_TRADE                 0x1111
#define LINKTYPE_TRADE_CONNECTING      0x1122
#define LINKTYPE_TRADE_SETUP           0x1133
#define LINKTYPE_TRADE_DISCONNECTED    0x1144
#define LINKTYPE_BATTLE                0x2211
#define LINKTYPE_0x2222                0x2222  // unused battle?
#define LINKTYPE_SINGLE_BATTLE         0x2233
#define LINKTYPE_DOUBLE_BATTLE         0x2244
#define LINKTYPE_MULTI_BATTLE          0x2255
#define LINKTYPE_BATTLE_TOWER_50       0x2266
#define LINKTYPE_BATTLE_TOWER_OPEN     0x2277
#define LINKTYPE_BATTLE_TOWER          0x2288
#define LINKTYPE_RECORD_MIX_BEFORE     0x3311
#define LINKTYPE_RECORD_MIX_AFTER      0x3322
#define LINKTYPE_BERRY_BLENDER_SETUP   0x4411
#define LINKTYPE_BERRY_BLENDER         0x4422
#define LINKTYPE_MYSTERY_EVENT         0x5501
#define LINKTYPE_0x5502                0x5502  // unused?
#define LINKTYPE_EREADER               0x5503
#define LINKTYPE_CONTEST_GMODE         0x6601
#define LINKTYPE_CONTEST_EMODE         0x6602

struct LinkStatus
{
    u32 localId:2;
    u32 playerCount:3;
    u32 master:1;
    u32 connEstablished:1;
    u32 unused_7:1;
    u32 receivedNothing:1;
    u32 unused_9:7;
    u32 errors:7;
};

#define MASTER_HANDSHAKE 0x8FFF
#define SLAVE_HANDSHAKE  0xB9A0

#define SIO_MULTI_CNT ((struct SioMultiCnt *)REG_ADDR_SIOCNT)

enum
{
    LINK_STATE_START0,
    LINK_STATE_START1,
    LINK_STATE_HANDSHAKE,
    LINK_STATE_INIT_TIMER,
    LINK_STATE_CONN_ESTABLISHED,
};

enum
{
    EXCHANGE_NOT_STARTED,
    EXCHANGE_COMPLETE,
    EXCHANGE_TIMED_OUT,
    EXCHANGE_DIFF_SELECTIONS,
    EXCHANGE_PLAYER_NOT_READY,
    EXCHANGE_PARTNER_NOT_READY,
    EXCHANGE_WRONG_NUM_PLAYERS,
    EXCHANGE_STAT_7
};

enum
{
    QUEUE_FULL_NONE,
    QUEUE_FULL_SEND,
    QUEUE_FULL_RECV,
};

enum
{
    LAG_NONE,
    LAG_MASTER,
    LAG_SLAVE,
};

struct LinkPlayer
{
    /* 0x00 */ u16 version;
    /* 0x02 */ u16 lp_field_2;
    /* 0x04 */ u32 trainerId;
    /* 0x08 */ u8 name[PLAYER_NAME_LENGTH + 1];
    /* 0x10 */ u8 progressFlags; // (& 0x0F) is hasNationalDex, (& 0xF0) is hasClearedGame
    /* 0x11 */ u8 neverRead;
    /* 0x12 */ u8 progressFlagsCopy;
    /* 0x13 */ u8 gender;
    /* 0x14 */ u32 linkType;
    /* 0x18 */ u16 id; // battler id in battles
    /* 0x1A */ u16 language;
};

struct LinkPlayerBlock
{
    char magic1[16];
    struct LinkPlayer linkPlayer;
    char magic2[16];
};

// circular queues

struct SendQueue
{
    /* 0x000 */ u16 data[CMD_LENGTH][QUEUE_CAPACITY];
    /* 0x320 */ u8 pos;
    /* 0x321 */ u8 count;
};

struct RecvQueue
{
    u16 data[MAX_LINK_PLAYERS][CMD_LENGTH][QUEUE_CAPACITY];
    u8 pos;
    u8 count;
};

struct Link
{
    /* 0x000 */ u8 isMaster; // 0: slave, 8: master
    /* 0x001 */ u8 state;
    /* 0x002 */ u8 localId; // local multi-player ID
    /* 0x003 */ u8 playerCount;
    /* 0x004 */ u16 tempRecvBuffer[4];
    /* 0x00c */ bool8 receivedNothing;
    /* 0x00d */ s8 serialIntrCounter;
    /* 0x00e */ bool8 handshakeAsMaster;
    /* 0x00f */ u8 link_field_F;

    // error conditions
    /* 0x010 */ bool8 hardwareError; // hardware reported an error
    /* 0x011 */ bool8 badChecksum; // checksum didn't match between devices
    /* 0x012 */ u8 queueFull; // send or recv queue out of space
    /* 0x013 */ u8 lag; // connection is lagging

    /* 0x014 */ u16 checksum;

    /* 0x016 */ u8 sendCmdIndex;
    /* 0x017 */ u8 recvCmdIndex;

    /* 0x018 */ struct SendQueue sendQueue;
    /* 0x33c */ struct RecvQueue recvQueue;
};

struct BlockRequest
{
    void * address;
    u32 size;
};

extern const struct BlockRequest sBlockRequestLookupTable[5];

extern struct Link gLink;
extern u16 gRecvCmds[MAX_RFU_PLAYERS][CMD_LENGTH];
extern u8 gBlockSendBuffer[BLOCK_BUFFER_SIZE];
extern u16 gLinkType;
extern u32 gLinkStatus;
extern u16 gBlockRecvBuffer[MAX_RFU_PLAYERS][BLOCK_BUFFER_SIZE / 2];
extern u16 gSendCmd[CMD_LENGTH];
extern struct LinkPlayer gLinkPlayers[5];
extern u16 word_3002910[];
extern bool8 gReceivedRemoteLinkPlayers;
extern u32 gBerryBlenderKeySendAttempts;
extern bool8 gLinkVSyncDisabled;
extern u32 gLinkStatus;

bool8 IsWirelessAdapterConnected(void);
void Task_DestroySelf(u8 taskId);
void OpenLink(void);
void CloseLink(void);
u16 LinkMain2(const u16 *);
void sub_8007B14(void);
bool32 sub_8007B24(void);
void ClearLinkCallback(void);
void ClearLinkCallback_2(void);
u8 GetLinkPlayerCount(void);
void OpenLinkTimed(void);
u8 GetLinkPlayerDataExchangeStatusTimed(int lower, int upper);
bool8 IsLinkPlayerDataExchangeComplete(void);
u32 GetLinkPlayerTrainerId(u8);
void ResetLinkPlayers(void);
void sub_8007E24(void);
void sub_8007E4C(void);
u8 GetMultiplayerId(void);
u8 bitmask_all_link_players_but_self(void);
bool8 SendBlock(u8, const void *, u16);
u8 GetBlockReceivedStatus(void);
void ResetBlockReceivedFlags(void);
void ResetBlockReceivedFlag(u8);
u8 GetLinkPlayerCount_2(void);
bool8 IsLinkMaster(void);
void CB2_LinkError(void);
u8 GetSioMultiSI(void);
bool8 IsLinkConnectionEstablished(void);
bool8 HasLinkErrorOccurred(void);
void ResetSerial(void);
u32 LinkMain1(u8 *shouldAdvanceLinkState, u16 *sendCmd, u16 (*recvCmds)[CMD_LENGTH]);
void LinkVSync(void);
void Timer3Intr(void);
void SerialCB(void);
bool32 InUnionRoom(void);
void LoadWirelessStatusIndicatorSpriteGfx(void);
bool8 IsLinkTaskFinished(void);
void CreateWirelessStatusIndicatorSprite(u8, u8);
void SetLinkStandbyCallback(void);
void SetWirelessCommType1(void);
void CheckShouldAdvanceLinkState(void);
u8 IsLinkMaster(void);
void SetCloseLinkCallback(void);
bool8 HandleLinkConnection(void);
void SetLinkDebugValues(u32 seed, u32 flags);
void SetBerryBlenderLinkCallback(void);
void SetSuppressLinkErrorMessage(bool8 flag);
void sub_800B524(struct LinkPlayer *linkPlayer);
u8 GetSioMultiSI(void);
void ClearSavedLinkPlayers(void);
void BufferLinkErrorInfo(u32 status, u8 lastSendQueueCount, u8 lastRecvQueueCount, u8 unk_06);
void sub_800B348(void);
void LinkPlayerFromBlock(u32 who);
bool32 Link_AnyPartnersPlayingFRLG_JP(void);
void ResetLinkPlayerCount(void);
void SaveLinkPlayers(u8 a0);
void SetWirelessCommType0(void);
bool32 sub_800B504(void);

extern u16 gLinkPartnersHeldKeys[6];
extern u32 gLinkDebugSeed;
extern struct LinkPlayerBlock gLocalLinkPlayerBlock;
extern bool8 gLinkErrorOccurred;
extern u32 gLinkDebugFlags;
extern bool8 gRemoteLinkPlayersNotReceived[MAX_LINK_PLAYERS];
extern u8 gBlockReceivedStatus[MAX_LINK_PLAYERS];
extern u16 gLinkHeldKeys;
extern u32 gLinkStatus;
extern u8 gUnknown_030030E4;
extern u8 gUnknown_030030E8;
extern bool8 gReadyToExitStandby[MAX_LINK_PLAYERS];
extern bool8 gReadyToCloseLink[MAX_LINK_PLAYERS];
extern u16 gReadyCloseLinkType;
extern u8 gSuppressLinkErrorMessage;
extern u8 gWirelessCommType;
extern bool8 gSavedLinkPlayerCount;
extern u8 gSavedMultiplayerId;
extern struct LinkTestBGInfo gLinkTestBGInfo;
extern void (*gLinkCallback)(void);
extern bool8 gShouldAdvanceLinkState;
extern u16 gLinkTestBlockChecksums[MAX_LINK_PLAYERS];
extern u8 gBlockRequestType;
extern u8 gLastSendQueueCount;
extern u8 gLastRecvQueueCount;
extern u16 gLinkSavedIme;
extern u32 gFiller_03003074;
extern u32 gFiller_03003154;
extern u32 gFiller_03003158;
extern u32 gFiller_0300315c;
extern u32 gFiller_03004138;
extern u32 gFiller_0300413C;
extern u32 gFiller_03003080;
extern struct LinkPlayer gLocalLinkPlayer;

bool32 Link_AnyPartnersPlayingRubyOrSapphire(void);
bool32 LinkDummy_Return2(void);
void SetLocalLinkPlayerId(u8);
u8 GetSavedPlayerCount(void);
void sub_8009FAC(void);
bool8 SendBlockRequest(u8 type);
u8 GetLinkPlayerCountAsBitFlags(void);
u8 sub_800A0C8(s32, s32);
u8 GetSavedLinkPlayerCountAsBitFlags(void);
void SetCloseLinkCallbackHandleJP(void);
void CheckLinkPlayersMatchSaved(void);
void StartSendingKeysToLink(void);
bool8 DoesLinkPlayerCountMatchSaved(void);
void SetCloseLinkCallbackAndType(u16 type);
bool32 IsSendingKeysToLink(void);
u32 GetLinkRecvQueueLength(void);

#endif // GUARD_LINK_H


code:
#ifndef GUARD_LINK_RFU_H
#define GUARD_LINK_RFU_H

#include "librfu.h"
#include "link.h"
#include "AgbRfu_LinkManager.h"

#define RFUCMD_SEND_PACKET         0x2F00
#define RFUCMD_BLENDER_SEND_KEYS   0x4400
#define RFUCMD_READY_CLOSE_LINK    0x5F00
#define RFUCMD_READY_EXIT_STANDBY  0x6600
#define RFUCMD_0x7700              0x7700
#define RFUCMD_0x7800              0x7800
#define RFUCMD_0x8800              0x8800
#define RFUCMD_0x8900              0x8900
#define RFUCMD_SEND_BLOCK_REQ      0xA100
#define RFUCMD_SEND_HELD_KEYS      0xBE00
#define RFUCMD_0xED00              0xED00
#define RFUCMD_0xEE00              0xEE00

#define RFU_SERIAL_7F7D 0x7F7D

#define RECV_QUEUE_NUM_SLOTS 32
#define RECV_QUEUE_SLOT_LENGTH (14 * MAX_RFU_PLAYERS)

#define SEND_QUEUE_NUM_SLOTS 40
#define SEND_QUEUE_SLOT_LENGTH 14

#define BACKUP_QUEUE_NUM_SLOTS 2
#define BACKUP_QUEUE_SLOT_LENGTH 14

#define RFU_PACKET_SIZE 6

#define RFU_STATUS_OK                   0
#define RFU_STATUS_FATAL_ERROR          1
#define RFU_STATUS_CONNECTION_ERROR     2
#define RFU_STATUS_CHILD_SEND_COMPLETE  3
#define RFU_STATUS_NEW_CHILD_DETECTED   4
#define RFU_STATUS_JOIN_GROUP_OK        5
#define RFU_STATUS_JOIN_GROUP_NO        6
#define RFU_STATUS_WAIT_ACK_JOIN_GROUP  7
#define RFU_STATUS_LEAVE_GROUP_NOTICE   8
#define RFU_STATUS_LEAVE_GROUP          9
#define RFU_STATUS_10                   10
#define RFU_STATUS_11                   11
#define RFU_STATUS_ACK_JOIN_GROUP       12

// RfuTgtData.gname is read as these structs.
struct GFtgtGnameSub
{
    u16 language:4;
    u16 hasNews:1;
    u16 hasCard:1;
    u16 unknown:1; // Never read
    u16 isChampion:1;
    u16 hasNationalDex:1;
    u16 gameClear:1;
    u16 version:4;
    u8 playerTrainerId[2];
};

struct __attribute__((packed, aligned(2))) GFtgtGname
{
    struct GFtgtGnameSub unk_00;
    u8 child_sprite_gender[RFU_CHILD_MAX]; // u8 sprite_idx:3;
    // u8 gender:1;
    // u8 unk_4:3
    // u8 active:1
    u16 species:10;
    u16 type:6;
    u8 activity:7;
    u8 started:1;
    u8 playerGender:1;
    u8 level:7;
    u8 padding;
}; // size: RFU_GNAME_SIZE

struct RfuBlockSend
{
    /* 0x00 */ u16 next;
    /* 0x02 */ u16 count;
    /* 0x04 */ const u8 *payload;
    /* 0x08 */ u32 receivedFlags;
    /* 0x0c */ u32 failedFlags;
    /* 0x10 */ bool8 sending;
    /* 0x11 */ u8 owner;
    /* 0x12 */ u8 receiving;
};

struct RfuRecvQueue
{
    /* 0x000 */ u8 slots[RECV_QUEUE_NUM_SLOTS][RECV_QUEUE_SLOT_LENGTH];
    /* 0x8c0 */ vu8 recvSlot;
    /* 0x8c1 */ vu8 sendSlot;
    /* 0x8c2 */ vu8 count;
    /* 0x8c3 */ vu8 full;
};

struct RfuSendQueue
{
    /* 0x000 */ u8 slots[SEND_QUEUE_NUM_SLOTS][SEND_QUEUE_SLOT_LENGTH];
    /* 0x230 */ vu8 recvSlot;
    /* 0x231 */ vu8 sendSlot;
    /* 0x232 */ vu8 count;
    /* 0x233 */ vu8 full;
};

struct RfuBackupQueue
{
    /* 0x00 */ u8 slots[BACKUP_QUEUE_NUM_SLOTS][BACKUP_QUEUE_SLOT_LENGTH];
    /* 0x1c */ vu8 recvSlot;
    /* 0x1d */ vu8 sendSlot;
    /* 0x1e */ vu8 count;
};

struct GFRfuManager
{
    /* 0x000 */ void (*callback)(void);
    /* 0x004 */ u16 state;
    /* 0x006 */ u8 filler_06[4];
    /* 0x00a */ u16 linkmanMsg;
    /* 0x00c */ u8 parentChild;
    /* 0x00d */ u8 playerCount;
    /* 0x00e */ bool8 unk_0e;
    /* 0x00f */ u8 unk_0f;
    /* 0x010 */ u16 unk_10;
    /* 0x012 */ u16 unk_12;
    /* 0x014 */ u8 unk_14[RFU_CHILD_MAX][14];
    /* 0x04c */ u8 unk_4c[14];
    /* 0x05a */ u8 blockRequestType;
    /* 0x05b */ u8 unk_5b;
    /* 0x05c */ bool8 blockReceived[MAX_RFU_PLAYERS];
    /* 0x061 */ bool8 numBlocksReceived[MAX_RFU_PLAYERS];
    /* 0x066 */ u8 idleTaskId;
    /* 0x067 */ u8 searchTaskId;
    /* 0x068 */ u8 filler_68[4];
    /* 0x06c */ struct RfuBlockSend sendBlock;
    /* 0x080 */ struct RfuBlockSend recvBlock[MAX_RFU_PLAYERS];
    /* 0x0e4 */ bool8 readyCloseLink[MAX_RFU_PLAYERS];
    /* 0x0e9 */ bool8 readyExitStandby[MAX_RFU_PLAYERS];
    /* 0x0ee */ vu8 errorState;
    /* 0x0ef */ bool8 isShuttingDown;
    /* 0x0f0 */ u8 linkLossRecoveryState;
    /* 0x0f1 */ u8 status;
    /* 0x0f2 */ u16 packet[RFU_PACKET_SIZE];
    /* 0x0fe */ u16 resendExitStandbyTimer;
    /* 0x100 */ u16 unk_100;
    /* 0x102 */ u8 unk_102;
    /* 0x103 */ u8 filler_103[0x10A - 0x103];
    /* 0x10A */ struct GFtgtGname unk_10A;
    u8 filler_;
    u8 playerName[PLAYER_NAME_LENGTH + 1];
    /* 0x124 */ struct RfuRecvQueue recvQueue;
    /* 0x9e8 */ struct RfuSendQueue sendQueue;
    /* 0xc1c */ struct RfuBackupQueue backupQueue;
    /* 0xc3c */ vu8 linkRecovered;
    /* 0xc3d */ u8 unk_c3d;
    /* 0xc3e */ vu8 childSlot;
    /* 0xc3f */ u8 unk_c3f[70];
    /* 0xc85 */ u8 unk_c85;
    /* 0xc86 */ u8 recvStatus;
    /* 0xc87 */ u8 recvCmds[5][7][2];
    /* 0xccd */ u8 parentId;
    /* 0xcce */ u8 multiplayerId;
    /* 0xccf */ u8 unk_ccf;
    /* 0xcd0 */ vu8 unk_cd0;
    /* 0xcd1 */ u8 partnerSendStatuses[RFU_CHILD_MAX];
    /* 0xcd5 */ u8 partnerRecvStatuses[RFU_CHILD_MAX];
    /* 0xcd9 */ u8 unk_cd9;
    /* 0xcda */ u8 unk_cda;
    /* 0xcdb */ vbool8 unk_cdb;
    /* 0xcdc */ vbool8 unk_cdc;
    /* 0xcdd */ u8 unk_cdd;
    /* 0xcde */ u8 linkPlayerIdx[RFU_CHILD_MAX];
    /* 0xce2 */ u8 unk_ce2;
    /* 0xce2 */ u8 unk_ce3;
    /* 0xce4 */ u8 unk_ce4;
    /* 0xce5 */ u8 unk_ce5;
    /* 0xce5 */ u8 unk_ce6;
    /* 0xce7 */ u8 acceptSlot_flag;
    /* 0xce8 */ u8 unk_ce8;
    /* 0xce9 */ u8 unk_ce9;
    /* 0xcea */ u8 unk_cea[4];
    /* 0xcee */ u8 unk_cee[4];
}; // size = 0xcf4

// Exported RAM declarations

extern struct GFtgtGname gHostRFUtgtGnameBuffer;
extern u8 gHostRFUtgtUnameBuffer[];
extern struct GFRfuManager Rfu;
extern u8 gWirelessStatusIndicatorSpriteId;

// Exported ROM declarations
void WipeTrainerNameRecords(void);
void InitRFUAPI(void);
void LinkRfu_Shutdown(void);
void Rfu_SetBlockReceivedFlag(u8 who);
void Rfu_ResetBlockReceivedFlag(u8 who);
bool32 IsSendingKeysToRfu(void);
void StartSendingKeysToRfu(void);
void Rfu_SetBerryBlenderLinkCallback(void);
u8 Rfu_GetBlockReceivedStatus(void);
bool32 Rfu_InitBlockSend(const u8 *src, size_t size);
void ClearLinkRfuCallback(void);
u8 Rfu_GetLinkPlayerCount(void);
u8 Rfu_GetMultiplayerId(void);
bool8 Rfu_SendBlockRequest(u8 type);
bool8 IsLinkRfuTaskFinished(void);
bool8 Rfu_IsMaster(void);
void Rfu_SetCloseLinkCallback(void);
void Rfu_SetLinkStandbyCallback(void);
void ResetLinkRfuGFLayer(void);
void UpdateWirelessStatusIndicatorSprite(void);
void InitRFU(void);
bool32 sub_8010EC0(void);
bool32 sub_8010F1C(void);
bool32 RfuHasErrored(void);
bool32 IsRfuRecvQueueEmpty(void);
u32 GetRfuRecvQueueLength(void);
void RfuVSync(void);
void sub_80111B0(bool32 a0);
u8 RfuGetStatus(void);
struct GFtgtGname *GetHostRFUtgtGname(void);
void UpdateGameData_GroupLockedIn(u8 a0);
void GetLinkmanErrorParams(u32 a0);
void RfuSetStatus(u8 a0, u16 a1);
u8 sub_801048C(bool32 a0);
void LinkRfu3_SetGnameUnameFromStaticBuffers(struct GFtgtGname *buff1, u8 *buff2);
void SetHostRFUtgtGname(u8 activity, u32 child_sprite_genders, bool32 started);
void InitializeRfuLinkManager_LinkLeader(u32 a0);
bool32 sub_8012240(void);
void LinkRfu_StopManagerAndFinalizeSlots(void);
bool32 sub_80105EC(void);
bool32 HasTrainerLeftPartnersList(u16 trainerId, const u8 *name);
void SendRfuStatusToPartner(u8 status, u16 trainerId, const u8 *name);
u32 WaitSendRfuStatusToPartner(u16 trainerId, const u8 *name);
void RequestDisconnectSlotByTrainerNameAndId(const u8 *a0, u16 a1);
bool8 LmanAcceptSlotFlagIsNotZero(void);
bool32 WaitRfuState(bool32 a0);
void sub_801103C(void);
void InitializeRfuLinkManager_JoinGroup(void);
void SendLeaveGroupNotice(void);
void RecordMixTrainerNames(void);
void LinkRfu_CreateConnectionAsParent(void);
void LinkRfu_StopManagerBeforeEnteringChat(void);
void UpdateGameData_SetActivity(u8 activity, u32 flags, bool32 started);
void CreateTask_RfuReconnectWithParent(const u8 *src, u16 trainerId);
void SetGnameBufferWonderFlags(bool32 a0, bool32 a1);
void ClearAndInitHostRFUtgtGname(void);
void SetTradeBoardRegisteredMonInfo(u32 type, u32 species, u32 level);
void InitializeRfuLinkManager_EnterUnionRoom(void);
void sub_8012188(const u8 *name, struct GFtgtGname *structPtr, u8 a2);
bool32 IsUnionRoomListenTaskActive(void);
void Rfu_SendPacket(void *data);
bool32 PlayerHasMetTrainerBefore(u16 id, u8 *name);
void sub_8011DE0(u32 arg0);
u8 sub_801100C(s32 a0);
void sub_800EF7C(void);
bool8 LinkRfu_GetNameIfCompatible(struct GFtgtGname *buff1, u8 *buff2, u8 idx);
bool8 LinkRfu_GetNameIfSerial7F7D(struct GFtgtGname *buff1, u8 *buff2, u8 idx);
s32 sub_800E87C(u8 idx);
void CreateTask_RfuIdle(void);
void DestroyTask_RfuIdle(void);
void sub_8011AC8(void);
void LinkRfu_FatalError(void);
bool32 sub_8011A9C(void);
void sub_80104B0(void);
void sub_8011A50(void);
void sub_80110B8(u32 a0);
bool32 IsRfuSerialNumberValid(u32 serialNo);
bool8 IsRfuRecoveringFromLinkLoss(void);
void RfuRecvQueue_Reset(struct RfuRecvQueue *queue);
void RfuSendQueue_Reset(struct RfuSendQueue *queue);
void RfuRecvQueue_Enqueue(struct RfuRecvQueue *queue, u8 *data);
void RfuSendQueue_Enqueue(struct RfuSendQueue *queue, u8 *data);
bool8 RfuRecvQueue_Dequeue(struct RfuRecvQueue *queue, u8 *dest);
bool8 RfuSendQueue_Dequeue(struct RfuSendQueue *queue, u8 *dest);
void RfuBackupQueue_Enqueue(struct RfuBackupQueue *queue, const u8 *q2);
bool8 RfuBackupQueue_Dequeue(struct RfuBackupQueue *queue, u8 *q2);
void InitHostRFUtgtGname(struct GFtgtGname *data, u8 activity, bool32 started, s32 child_sprite_genders);
void CreateWirelessStatusIndicatorSprite(u8 x, u8 y);
void DestroyWirelessStatusIndicatorSprite(void);
void LoadWirelessStatusIndicatorSpriteGfx(void);

#endif //GUARD_LINK_RFU_H


code:
#ifndef GUARD_LIST_MENU_H
#define GUARD_LIST_MENU_H

#include "window.h"

#define LIST_NOTHING_CHOSEN -1
#define LIST_CANCEL -2
#define LIST_HEADER -3

#define LIST_NO_MULTIPLE_SCROLL     0
#define LIST_MULTIPLE_SCROLL_DPAD   1
#define LIST_MULTIPLE_SCROLL_L_R    2

enum
{
    SCROLL_ARROW_LEFT,
    SCROLL_ARROW_RIGHT,
    SCROLL_ARROW_UP,
    SCROLL_ARROW_DOWN
};

struct ListMenu;

struct ListMenuItem
{
    const u8 *name;
    s32 id;
};

struct ListMenuTemplate
{
    const struct ListMenuItem *items;
    void (* moveCursorFunc)(s32 itemIndex, bool8 onInit, struct ListMenu *list);
    void (* itemPrintFunc)(u8 windowId, s32 itemId, u8 y);
    u16 totalItems;
    u16 maxShowed;
    u8 windowId;
    u8 header_X;
    u8 item_X;
    u8 cursor_X;
    u8 upText_Y:4; // x1, x2, x4, x8 = xF
    u8 cursorPal:4; // x10, x20, x40, x80 = xF0
    u8 fillValue:4; // x1, x2, x4, x8 = xF
    u8 cursorShadowPal:4; // x10, x20, x40, x80 = xF0
    u8 lettersSpacing:3;
    u8 itemVerticalPadding:3;
    u8 scrollMultiple:2; // x40, x80 = xC0
    u8 fontId:6; // x1, x2, x4, x8, x10, x20 = x3F
    u8 cursorKind:2; // x40, x80
};

struct ListMenu
{
    struct ListMenuTemplate template;
    u16 scrollOffset;
    u16 selectedRow;
    u8 unk_1C;
    u8 unk_1D;
    u8 taskId;
    u8 unk_1F;
};

struct ListMenuWindowRect
{
    u8 x;
    u8 y;
    u8 width;
    u8 height;
    u8 palNum;
};

struct ScrollArrowsTemplate
{
    u8 firstArrowType;
    u8 firstX;
    u8 firstY;
    u8 secondArrowType;
    u8 secondX;
    u8 secondY;
    u16 fullyUpThreshold;
    u16 fullyDownThreshold;
    u16 tileTag;
    u16 palTag;
    u8 palNum;
};

struct CursorStruct
{
    u8 left;
    u8 top;
    u16 rowWidth;
    u16 rowHeight;
    u16 tileTag;
    u16 palTag;
    u8 palNum;
};

extern struct ScrollArrowsTemplate gTempScrollArrowTemplate;
extern struct ListMenuTemplate gMultiuseListMenuTemplate;

s32 DoMysteryGiftListMenu(const struct WindowTemplate *windowTemplate, const struct ListMenuTemplate *listMenuTemplate, u8 arg2, u16 tileNum, u16 palNum);
u8 ListMenuInit(struct ListMenuTemplate *listMenuTemplate, u16 scrollOffset, u16 selectedRow);
u8 ListMenuInitInRect(struct ListMenuTemplate *listMenuTemplate, struct ListMenuWindowRect *arg1, u16 scrollOffset, u16 selectedRow);
s32 ListMenu_ProcessInput(u8 listTaskId);
void DestroyListMenuTask(u8 listTaskId, u16 *scrollOffset, u16 *selectedRow);
void RedrawListMenu(u8 listTaskId);
void ChangeListMenuPals(u8 listTaskId, u8 cursorPal, u8 fillValue, u8 cursorShadowPal);
void ChangeListMenuCoords(u8 listTaskId, u8 x, u8 y);
s32 ListMenuTestInput(struct ListMenuTemplate *template, u32 scrollOffset, u32 selectedRow, u16 keys, u16 *newScrollOffset, u16 *newSelectedRow);
void ListMenuGetCurrentItemArrayId(u8 listTaskId, u16 *arrayId);
void ListMenuGetScrollAndRow(u8 listTaskId, u16 *scrollOffset, u16 *selectedRow);
u16 ListMenuGetYCoordForPrintingArrowCursor(u8 listTaskId);
void ListMenuOverrideSetColors(u8 cursorPal, u8 fillValue, u8 cursorShadowPal);
void ListMenuDefaultCursorMoveFunc(s32 arg0, u8 arg1, struct ListMenu *list);
s32 ListMenuGetUnkIndicatorsStructFields(u8 taskId, u8 field);
void ListMenuSetUnkIndicatorsStructField(u8 taskId, u8 field, s32 value);
u8 AddScrollIndicatorArrowPair(const struct ScrollArrowsTemplate *arrowInfo, u16 *arg1);
u8 AddScrollIndicatorArrowPairParameterized(u32 arrowType, s32 commonPos, s32 firstPos, s32 secondPos, s32 fullyDownThreshold, s32 tileTag, s32 palTag, u16 *currItemPtr);
void RemoveScrollIndicatorArrowPair(u8 taskId);
void Task_ScrollIndicatorArrowPairOnMainMenu(u8 taskId);

#endif //GUARD_LIST_MENU_H


code:
#ifndef GUARD_LOAD_SAVE_H
#define GUARD_LOAD_SAVE_H

extern struct SaveBlock1 gSaveblock1;
extern struct SaveBlock2 gSaveblock2;
extern struct PokemonStorage gPokemonStorage;

extern bool32 gFlashMemoryPresent;
extern struct SaveBlock1 *gSaveBlock1Ptr;
extern struct SaveBlock2 *gSaveBlock2Ptr;
extern struct PokemonStorage *gPokemonStoragePtr;

void CheckForFlashMemory(void);
void ClearSav2(void);
void ClearSav1(void);
void SetSaveBlocksPointers(u16 offset);
void MoveSaveBlocks_ResetHeap(void);
u32 UseContinueGameWarp(void);
void ClearContinueGameWarpStatus(void);
void SetContinueGameWarpStatus(void);
void SetContinueGameWarpStatusToDynamicWarp(void);
void ClearContinueGameWarpStatus2(void);
void SavePlayerParty(void);
void LoadPlayerParty(void);
void SaveObjectEvents(void);
void LoadObjectEvents(void);
void SaveSerializedGame(void);
void LoadSerializedGame(void);
void LoadPlayerBag(void);
void SavePlayerBag(void);
void ApplyNewEncryptionKeyToHword(u16 *hWord, u32 newKey);
void ApplyNewEncryptionKeyToWord(u32 *word, u32 newKey);

#endif // GUARD_LOAD_SAVE_H


code:
#ifndef GUARD_LOTTERY_CORNER_H
#define GUARD_LOTTERY_CORNER_H

void ResetLotteryCorner(void);
void SetRandomLotteryNumber(u16 i);
void RetrieveLotteryNumber(void);
void PickLotteryCornerTicket(void);
void SetLotteryNumber(u32 lotteryNum);
u32 GetLotteryNumber(void);
void SetLotteryNumber16_Unused(u16 lotteryNum);

#endif // GUARD_LOTTERY_CORNER_H


code:
#ifndef GUARD_M4A_H
#define GUARD_M4A_H

#include "gba/m4a_internal.h"

void m4aSoundVSync(void);
void m4aSoundVSyncOn(void);

void m4aSoundInit(void);
void m4aSoundMain(void);
void m4aSongNumStart(u16 n);
void m4aSongNumStartOrChange(u16 n);
void m4aSongNumStop(u16 n);
void m4aMPlayAllStop(void);
void m4aMPlayContinue(struct MusicPlayerInfo *mplayInfo);
void m4aMPlayFadeOut(struct MusicPlayerInfo *mplayInfo, u16 speed);
void m4aMPlayFadeOutTemporarily(struct MusicPlayerInfo *mplayInfo, u16 speed);
void m4aMPlayFadeIn(struct MusicPlayerInfo *mplayInfo, u16 speed);
void m4aMPlayImmInit(struct MusicPlayerInfo *mplayInfo);

extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern struct MusicPlayerInfo gMPlayInfo_SE1;
extern struct MusicPlayerInfo gMPlayInfo_SE2;
extern struct MusicPlayerInfo gMPlayInfo_SE3;
extern struct SoundInfo gSoundInfo;

#endif //GUARD_M4A_H


code:
#ifndef GUARD_MAIL_H
#define GUARD_MAIL_H

#define IS_ITEM_MAIL(itemId)((itemId == ITEM_ORANGE_MAIL            \
                              || itemId == ITEM_HARBOR_MAIL         \
                              || itemId == ITEM_GLITTER_MAIL        \
                              || itemId == ITEM_MECH_MAIL           \
                              || itemId == ITEM_WOOD_MAIL           \
                              || itemId == ITEM_WAVE_MAIL           \
                              || itemId == ITEM_BEAD_MAIL           \
                              || itemId == ITEM_SHADOW_MAIL         \
                              || itemId == ITEM_TROPIC_MAIL         \
                              || itemId == ITEM_DREAM_MAIL          \
                              || itemId == ITEM_FAB_MAIL            \
                              || itemId == ITEM_RETRO_MAIL))

// mail.h
void ReadMail(struct MailStruct *mail, void (*callback)(void), bool8 flag);

// mail_data.h
void ClearMailData(void);
void ClearMailStruct(struct MailStruct *mail);
bool8 MonHasMail(struct Pokemon *mon);
u8 GiveMailToMon(struct Pokemon *mon, u16 itemId);
u16 SpeciesToMailSpecies(u16 species, u32 personality);
u16 MailSpeciesToSpecies(u16 mailSpecies, u16 *buffer);
u8 GiveMailToMon2(struct Pokemon *mon, struct MailStruct *mail);
void TakeMailFromMon(struct Pokemon *mon);
void ClearMailItemId(u8 mailId);
u8 TakeMailFromMon2(struct Pokemon *mon);
bool8 ItemIsMail(u16 itemId);

#endif // GUARD_MAIL_H


code:
#ifndef GUARD_MAIN_H
#define GUARD_MAIN_H

typedef void (*MainCallback)(void);
typedef void (*IntrCallback)(void);
typedef void (*IntrFunc)(void);

struct Main
{
    /*0x000*/ MainCallback callback1;
    /*0x004*/ MainCallback callback2;

    /*0x008*/ MainCallback savedCallback;

    /*0x00C*/ IntrCallback vblankCallback;
    /*0x010*/ IntrCallback hblankCallback;
    /*0x014*/ IntrCallback vcountCallback;
    /*0x018*/ IntrCallback serialCallback;

    /*0x01C*/ vu16 intrCheck;

    /*0x020*/ u32 vblankCounter1;
    /*0x024*/ u32 vblankCounter2;

    /*0x028*/ u16 heldKeysRaw;           // held keys without L=A remapping
    /*0x02A*/ u16 newKeysRaw;            // newly pressed keys without L=A remapping
    /*0x02C*/ u16 heldKeys;              // held keys with L=A remapping
    /*0x02E*/ u16 newKeys;               // newly pressed keys with L=A remapping
    /*0x030*/ u16 newAndRepeatedKeys;    // newly pressed keys plus key repeat
    /*0x032*/ u16 keyRepeatCounter;      // counts down to 0, triggering key repeat
    /*0x034*/ bool16 watchedKeysPressed; // whether one of the watched keys was pressed
    /*0x036*/ u16 watchedKeysMask;       // bit mask for watched keys

    /*0x038*/ struct OamData oamBuffer[128];

    /*0x438*/ u8 state;

    /*0x439*/ u8 oamLoadDisabled:1;
    /*0x439*/ u8 inBattle:1;
    /*0x439*/ u8 field_439_x4:1;
};

extern const u8 gGameVersion;
extern const u8 gGameLanguage;
extern const u8 RomHeaderGameCode[4];
extern const u8 RomHeaderSoftwareVersion;

extern u16 gKeyRepeatStartDelay;
extern bool8 gLinkTransferringData;
extern struct Main gMain;
extern u16 gKeyRepeatContinueDelay;
extern bool8 gSoftResetDisabled;
extern IntrFunc gIntrTable[];
extern u8 gLinkVSyncDisabled;
extern u32 IntrMain_Buffer[];
extern s8 gPcmDmaCounter;

void AgbMain(void);
void SetMainCallback2(MainCallback callback);
void InitKeys(void);
void SetVBlankCallback(IntrCallback callback);
void SetHBlankCallback(IntrCallback callback);
void SetVCountCallback(IntrCallback callback);
void SetSerialCallback(IntrCallback callback);
void InitFlashTimer(void);
void SetTrainerHillVBlankCounter(u32 *var);
void ClearTrainerHillVBlankCounter(void);
void DoSoftReset(void);
void ClearPokemonCrySongs(void);
void RestoreSerialTimer3IntrHandlers(void);
void StartTimer1(void);
void SeedRngAndSetTrainerId(void);
u16 GetGeneratedTrainerIdLower(void);
void sub_819789C(void);

#endif // GUARD_MAIN_H


code:
#ifndef GUARD_MAIN_MENU_H
#define GUARD_MAIN_MENU_H

void CB2_InitMainMenu(void);
void CreateYesNoMenuParameterized(u8 a, u8 b, u16 c, u16 d, u8 e, u8 f);

#endif // GUARD_MAIN_MENU_H


code:
#ifndef GUARD_MAP_NAME_POPUP_H
#define GUARD_MAP_NAME_POPUP_H

// Exported type declarations

// Exported RAM declarations

// Exported ROM declarations
void HideMapNamePopUpWindow(void);
void ShowMapNamePopup(void);
#endif //GUARD_MAP_NAME_POPUP_H


code:
#ifndef GUARD_MATCH_CALL_H
#define GUARD_MATCH_CALL_H

enum {
    MATCH_CALL_TYPE_NON_TRAINER,
    MATCH_CALL_TYPE_TRAINER,
    MATCH_CALL_TYPE_WALLY,
    MATCH_CALL_TYPE_BIRCH,
    MATCH_CALL_TYPE_MAY_BRENDAN,
    MATCH_CALL_TYPE_GYMLEADER_ELITEFOUR
};

s32 GetRematchIdxByTrainerIdx(s32 trainerIdx);
void InitMatchCallCounters(void);
bool32 TryStartMatchCall(void);
bool32 IsMatchCallTaskActive(void);
void StartMatchCallFromScript(const u8 *message);
void BufferPokedexRatingForMatchCall(u8 *destStr);
bool32 SelectMatchCallMessage(int, u8 *);
void sub_8197184(u32 windowId, u32 destOffset, u32 paletteId);
void sub_81971C4(u32 windowId, u32 tileOffset, u32 paletteId);

#endif //GUARD_MATCH_CALL_H


code:
#ifndef GUARD_MATH_UTIL_H
#define GUARD_MATH_UTIL_H

s16 MathUtil_Mul16(s16 x, s16 y);
s16 MathUtil_Mul16Shift(u8 s, s16 x, s16 y);
s32 MathUtil_Mul32(s32 x, s32 y);
s16 MathUtil_Div16(s16 x, s16 y);
s16 MathUtil_Div16Shift(u8 s, s16 x, s16 y);
s32 MathUtil_Div32(s32 x, s32 y);
s16 MathUtil_Inv16(s16 y);
s16 MathUtil_Inv16Shift(u8 s, s16 y);
s32 MathUtil_Inv32(s32 y);

#endif // GUARD_MATH_UTIL_H


code:
#ifndef GUARD_MAUVILLE_OLD_MAN_H
#define GUARD_MAUVILLE_OLD_MAN_H

extern struct BardSong gBardSong;

void SetMauvilleOldMan(void);
u8 GetCurrentMauvilleOldMan(void);
void ScrSpecial_SetMauvilleOldManObjEventGfx(void);
u8 sub_81201C8(void);
void sub_8120B70(OldMan *dest);
void sub_8120670(void);
void SanitizeReceivedRubyOldMan(union OldMan * oldMan, u32 r1, u32 r6);
void SanitizeReceivedEmeraldOldMan(union OldMan * oldMan, u32 unused, u32 a2);
void ResetMauvilleOldManFlag(void);

#endif // GUARD_MAUVILLE_OLD_MAN_H


code:
#ifndef GUARD_MENU_H
#define GUARD_MENU_H

#include "task.h"
#include "text.h"
#include "window.h"
#include "constants/pokemon.h"

#define MENU_NOTHING_CHOSEN -2
#define MENU_B_PRESSED -1

#define MENU_CURSOR_DELTA_NONE   0
#define MENU_CURSOR_DELTA_UP    -1
#define MENU_CURSOR_DELTA_DOWN   1
#define MENU_CURSOR_DELTA_LEFT  -1
#define MENU_CURSOR_DELTA_RIGHT  1

#define MENU_INFO_ICON_TYPE      (NUMBER_OF_MON_TYPES + 1)
#define MENU_INFO_ICON_POWER     (NUMBER_OF_MON_TYPES + 2)
#define MENU_INFO_ICON_ACCURACY  (NUMBER_OF_MON_TYPES + 3)
#define MENU_INFO_ICON_PP        (NUMBER_OF_MON_TYPES + 4)
#define MENU_INFO_ICON_EFFECT    (NUMBER_OF_MON_TYPES + 5)
#define MENU_INFO_ICON_BALL_RED  (NUMBER_OF_MON_TYPES + 6)
#define MENU_INFO_ICON_BALL_BLUE (NUMBER_OF_MON_TYPES + 7)

enum
{
    SAVE_MENU_NAME,
    SAVE_MENU_CAUGHT,
    SAVE_MENU_PLAY_TIME,
    SAVE_MENU_LOCATION,
    SAVE_MENU_BADGES,
};

struct MenuAction
{
    const u8 *text;
    union {
        void (*void_u8)(u8);
        u8 (*u8_void)(void);
    } func;
};

extern const u16 gUnknown_0860F074[];

void FreeAllOverworldWindowBuffers(void);
void InitStandardTextBoxWindows(void);
void InitTextBoxGfxAndPrinters(void);
u16 RunTextPrintersAndIsPrinter0Active(void);
void LoadMessageBoxAndBorderGfx(void);
void DrawDialogueFrame(u8 windowId, bool8 copyToVram);
void ClearStdWindowAndFrame(u8 windowId, bool8 copyToVram);
u16 AddTextPrinterParameterized2(u8 windowId, u8 fontId, const u8 *str, u8 speed, void (*callback)(struct TextPrinterTemplate *, u16), u8 fgColor, u8 bgColor, u8 shadowColor);
void PrintPlayerNameOnWindow(u8, const u8*, u16, u16);
void ClearDialogWindowAndFrame(u8 windowId, bool8 copyToVram);
void SetStandardWindowBorderStyle(u8 windowId, bool8 copyToVram);
void DisplayYesNoMenuDefaultYes(void);
u32 GetPlayerTextSpeed(void);
u8 GetPlayerTextSpeedDelay(void);
void Menu_LoadStdPalAt(u16 arg0);
void AddTextPrinterWithCallbackForMessage(bool8 a1, void (*callback)(struct TextPrinterTemplate *, u16));
void sub_8199DF0(u32 bg, u8 a1, int a2, int a3);
void AddTextPrinterParameterized3(u8 windowId, u8 fontId, u8 left, u8 top, const u8 *color, s8 speed, const u8 *str);
void ClearStdWindowAndFrameToTransparent(u8 windowId, bool8 copyToVram);
void SetWindowTemplateFields(struct WindowTemplate* template, u8 priority, u8 tilemapLeft, u8 tilemapTop, u8 width, u8 height, u8 palNum, u16 baseBlock);
void DrawStdFrameWithCustomTileAndPalette(u8 windowId, bool8 copyToVram, u16 tileStart, u8 palette);
void ScheduleBgCopyTilemapToVram(u8 bgNum);
void PrintMenuTable(u8 windowId, u8 itemCount, const struct MenuAction *strs);
u8 InitMenuInUpperLeftCornerPlaySoundWhenAPressed(u8 windowId, u8 numItems, u8 initialCursorPos);
u8 Menu_GetCursorPos(void);
s8 Menu_ProcessInput(void);
s8 Menu_ProcessInputNoWrap(void);
void BlitMenuInfoIcon(u8 winId, u8 a2, u16 x, u16 y);
void ResetTempTileDataBuffers(void);
void *DecompressAndCopyTileDataToVram(u8 bgId, const void *src, u32 size, u16 offset, u8 mode);
bool8 FreeTempTileDataBuffersIfPossible(void);
struct WindowTemplate CreateWindowTemplate(u8 bg, u8 left, u8 top, u8 width, u8 height, u8 paletteNum, u16 baseBlock);
void CreateYesNoMenu(const struct WindowTemplate *windowTemplate, u16 borderFirstTileNum, u8 borderPalette, u8 initialCursorPos);
void DecompressAndLoadBgGfxUsingHeap(u8 bgId, const void *src, u32 size, u16 offset, u8 mode);
s8 Menu_ProcessInputNoWrapClearOnChoose(void);
s8 ProcessMenuInput_other(void);
void DoScheduledBgTilemapCopiesToVram(void);
void ClearScheduledBgCopiesToVram(void);
void AddTextPrinterParameterized4(u8 windowId, u8 fontId, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, const u8 *color, s8 speed, const u8 *str);
void DrawDialogFrameWithCustomTileAndPalette(u8 windowId, bool8 copyToVram, u16 a2, u8 a3);
void sub_81995E4(u8 windowId, u8 optionsNo, const struct MenuAction *actions, const u8 *actionIds);
void ClearDialogWindowAndFrameToTransparent(u8 windowId, bool8 copyToVram);
u16 sub_8198AA4(u8, u8, u8, u8, u8, u8, u16);
void *malloc_and_decompress(const void *src, u32 *sizeOut);
u16 copy_decompressed_tile_data_to_vram(u8 bgId, const void *src, u16 size, u16 offset, u8 mode);
void AddTextPrinterForMessage(bool8 allowSkippingDelayWithButtonPress);
void AddItemMenuActionTextPrinters(u8 windowId, u8 fontId, u8 left, u8 top, u8 letterSpacing, u8 lineHeight, u8 itemCount, const struct MenuAction *strs, const u8 *a8);
void sub_8198DBC(u8 windowId, u8 fontId, u8 left, u8 top, u8 a4, u8 itemCount, u8 itemCount2, const struct MenuAction *strs, const u8 *a8);
u8 sub_8199944(u8 windowId, u8 optionWidth, u8 columns, u8 rows, u8 initialCursorPos);
u8 ChangeListMenuCursorPosition(s8 deltaX, s8 deltaY);
u8 GetStartMenuWindowId(void);
void ListMenuLoadStdPalAt(u8, u8);
u8 Menu_MoveCursor(s8 cursorDelta);
u8 Menu_MoveCursorNoWrapAround(s8 cursorDelta);
void DrawStdWindowFrame(u8 windowId, bool8 CopyToVram);
u8 sub_81979C4(u8 a1);
u8 sub_81983AC(u8 windowId, u8 fontId, u8 left, u8 top, u8 cursorHeight, u8 numChoices, u8 initialCursorPos);
void sub_819786C(u8 windowId, bool8 copyToVram);
void AddTextPrinterForMessage_2(bool8 allowSkippingDelayWithButtonPress);
void RemoveStartMenuWindow(void);
void DisplayYesNoMenuWithDefault(u8 initialCursorPos);
void BufferSaveMenuText(u8 textId, u8 *dest, u8 color);
void RemoveMapNamePopUpWindow(void);
u8 GetMapNamePopUpWindowId(void);
u8 AddMapNamePopUpWindow(void);
void AddTextPrinterParameterized5(u8 windowId, u8 fontId, const u8 *str, u8 left, u8 top, u8 speed, void (*callback)(struct TextPrinterTemplate *, u16), u8 letterSpacing, u8 lineSpacing);
void SetBgTilemapPalette(u8 bgId, u8 left, u8 top, u8 width, u8 height, u8 palette);
void sub_8199D3C(void *ptr, int delta, int width, int height, bool32 is8BPP);
void sub_8198204(const u8 *string, const u8 *string2, u8 a3, u8 a4, bool8 copyToVram);
void sub_8197AE8(bool8 copyToVram);
void PrintMenuGridTable(u8 windowId, u8 optionWidth, u8 columns, u8 rows, const struct MenuAction *strs);
s8 Menu_ProcessInputGridLayout(void);
u8 InitMenuInUpperLeftCorner(u8 windowId, u8 itemCount, u8 initialCursorPos, bool8 APressMuted);
s8 Menu_ProcessInputNoWrapAround_other(void);
void CopyToBufferFromBgTilemap(u8 bgId, u16 *dest, u8 left, u8 top, u8 width, u8 height);
u8 sub_81980F0(u8 bg, u8 xPos, u8 yPos, u8 palette, u16 baseTile);
void sub_8198314(void);
void sub_8198180(const u8 *string, u8 a2, bool8 copyToVram);
void ResetBgPositions(void);
void AddTextPrinterWithCustomSpeedForMessage(bool8 allowSkippingDelayWithButtonPress, u8 speed);
void sub_8198C78(void);
void PrintTextArray(u8 windowId, u8 fontId, u8 left, u8 top, u8 lineHeight, u8 itemCount, const struct MenuAction *strs);

#endif // GUARD_MENU_H


code:
#ifndef GUARD_MENU_HELPERS_H
#define GUARD_MENU_HELPERS_H

#include "task.h"
#include "window.h"

#define MENU_L_PRESSED 1
#define MENU_R_PRESSED 2

// Exported type declarations

struct YesNoFuncTable
{
    TaskFunc yesFunc;
    TaskFunc noFunc;
};

// Exported RAM declarations

// Exported ROM declarations
void ResetVramOamAndBgCntRegs(void);
void ResetAllBgsCoordinates(void);
void SetVBlankHBlankCallbacksToNull(void);
void DisplayMessageAndContinueTask(u8 taskId, u8 windowId, u16 arg2, u8 arg3, u8 fontId, u8 textSpeed, const u8 *string, void *taskFunc);
bool16 RunTextPrintersRetIsActive(u8 textPrinterId);
void DoYesNoFuncWithChoice(u8 taskId, const struct YesNoFuncTable *data);
void CreateYesNoMenuWithCallbacks(u8 taskId, const struct WindowTemplate *template, u8 arg2, u8 arg3, u8 arg4, u16 tileStart, u8 palette, const struct YesNoFuncTable *yesNo);
bool8 AdjustQuantityAccordingToDPadInput(s16 *arg0, u16 arg1);
u8 GetLRKeysPressed(void);
u8 GetLRKeysPressedAndHeld(void);
bool8 sub_8122148(u16 itemId);
bool8 itemid_80BF6D8_mail_related(u16 itemId);
bool8 MenuHelpers_LinkSomething(void);
bool8 MenuHelpers_CallLinkSomething(void);
void sub_812220C(struct ItemSlot *slots, u8 count, u8 *arg2, u8 *usedSlotsCount, u8 maxUsedSlotsCount);
void sub_812225C(u16 *scrollOffset, u16 *cursorPos, u8 maxShownItems, u8 numItems);
void sub_8122298(u16 *arg0, u16 *arg1, u8 arg2, u8 arg3, u8 arg4);
void LoadListMenuArrowsGfx(void);
void sub_8122344(u8 *spriteIds, u8 count);
void sub_81223B0(u8 *spriteIds, u8 count);
void sub_81223FC(u8 *spriteIds, u8 count, bool8 invisible);
void sub_8122448(u8 *spriteIds, u8 count, s16 x, u16 y);

#endif //GUARD_MENU_HELPERS_H


code:
#ifndef GUARD_MENU_SPECIALIZED_H
#define GUARD_MENU_SPECIALIZED_H

#include "sprite.h"
#include "player_pc.h"
#include "list_menu.h"
#include "pokemon.h"
#include "constants/berry.h"

#define TAG_CONDITION_MON              100
#define TAG_CONDITION_BALL             101
#define TAG_CONDITION_CANCEL           102
#define TAG_CONDITION_BALL_PLACEHOLDER 103
#define TAG_CONDITION_SPARKLE          104

#define MAX_CONDITION_SPARKLES 10

struct UnknownSubStruct_81D1ED4
{
    u16 unk0;
    u16 unk2;
};

struct ConditionGraph
{
    /*0x000*/ u8 stat[4][FLAVOR_COUNT];
    /*0x014*/ struct UnknownSubStruct_81D1ED4 unk14[4][FLAVOR_COUNT];
    /*0x064*/ struct UnknownSubStruct_81D1ED4 unk64[10][FLAVOR_COUNT];
    /*0x12C*/ struct UnknownSubStruct_81D1ED4 unk12C[FLAVOR_COUNT];
    /*0x140*/ u16 unk140[66][2];
    /*0x248*/ u16 unk248[66][2];
    /*0x350*/ u16 unk350;
    /*0x352*/ u16 unk352;
    /*0x354*/ u8 unk354;
    /*0x355*/ u8 state;
};

bool8 sub_81D1C44(u8 count);
u8 sub_81D1C84(u8 a0);
u8 sub_81D1DC0(struct PlayerPCItemPageStruct *page);
void sub_81D1E90(struct PlayerPCItemPageStruct *page);
void sub_81D1EC0(void);
void sub_81D1D04(u8 a0);
void InitConditionGraphData(struct ConditionGraph *graph);
void sub_81D2108(struct ConditionGraph *graph);
void SetConditionGraphIOWindows(u8 bg);
void InitConditionGraphState(struct ConditionGraph *graph);
void sub_81D2230(struct ConditionGraph *graph);
bool8 SetupConditionGraphScanlineParams(struct ConditionGraph *graph);
bool32 TransitionConditionGraph(struct ConditionGraph *graph);
void sub_81D2754(u8 *arg0, struct UnknownSubStruct_81D1ED4 *arg1);
void sub_81D1F84(struct ConditionGraph *graph, struct UnknownSubStruct_81D1ED4 *arg1, struct UnknownSubStruct_81D1ED4 *arg2);
void MoveRelearnerPrintText(u8 *str);
bool16 MoveRelearnerRunTextPrinters(void);
void MoveRelearnerCreateYesNoMenu(void);
u8 LoadMoveRelearnerMovesList(const struct ListMenuItem *items, u16 numChoices);
void InitMoveRelearnerWindows(bool8 useContextWindow);
s32 GetBoxOrPartyMonData(u16 boxId, u16 monId, s32 request, u8 *dst);
void GetConditionMenuMonNameAndLocString(u8 *locationDst, u8 *nameDst, u16 boxId, u16 monId, u16 partyId, u16 numMons, bool8 excludesCancel);
void GetConditionMenuMonConditions(struct ConditionGraph *graph, u8 *sheen, u16 boxId, u16 monId, u16 partyId, u16 id, u16 numMons, bool8 excludesCancel);
void GetConditionMenuMonGfx(void *tilesDst, void *palDst, u16 boxId, u16 monId, u16 partyId, u16 numMons, bool8 excludesCancel);
bool8 MoveConditionMonOnscreen(s16 *x);
bool8 MoveConditionMonOffscreen(s16 *x);
bool8 TryUpdateConditionMonTransitionOn(struct ConditionGraph *graph, s16 *x);
bool8 TryUpdateConditionMonTransitionOff(struct ConditionGraph *graph, s16 *x);
void LoadConditionMonPicTemplate(struct SpriteSheet *sheet, struct SpriteTemplate *template, struct SpritePalette *pal);
void LoadConditionSelectionIcons(struct SpriteSheet *sheets, struct SpriteTemplate * template, struct SpritePalette *pals);
void LoadConditionSparkle(struct SpriteSheet *sheet, struct SpritePalette *pal);
void ResetConditionSparkleSprites(struct Sprite **sprites);
void CreateConditionSparkleSprites(struct Sprite **sprites, u8 monSpriteId, u8 count);
void DestroyConditionSparkleSprites(struct Sprite **sprites);
void FreeConditionSparkles(struct Sprite **sprites);
void DrawLevelUpWindowPg1(u16 windowId, u16 *statsBefore, u16 *statsAfter, u8 bgClr, u8 fgClr, u8 shadowClr);
void DrawLevelUpWindowPg2(u16 windowId, u16 *currStats, u8 bgClr, u8 fgClr, u8 shadowClr);
void GetMonLevelUpWindowStats(struct Pokemon *mon, u16 *currStats);

#endif // GUARD_MENU_SPECIALIZED_H