Merge branch 'master' into doc-menu

This commit is contained in:
GriffinR 2021-11-04 12:11:31 -04:00 committed by GitHub
commit be7d0bd3b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 842 additions and 899 deletions

View File

@ -7,6 +7,9 @@
#define OAM_MATRIX_COUNT 32 #define OAM_MATRIX_COUNT 32
#define sAnchorX data[6]
#define sAnchorY data[7]
#define SET_SPRITE_TILE_RANGE(index, start, count) \ #define SET_SPRITE_TILE_RANGE(index, start, count) \
{ \ { \
sSpriteTileRanges[index * 2] = start; \ sSpriteTileRanges[index * 2] = start; \
@ -91,7 +94,7 @@ static void ApplyAffineAnimFrame(u8 matrixNum, struct AffineAnimFrameCmd *frameC
static u8 IndexOfSpriteTileTag(u16 tag); static u8 IndexOfSpriteTileTag(u16 tag);
static void AllocSpriteTileRange(u16 tag, u16 start, u16 count); static void AllocSpriteTileRange(u16 tag, u16 start, u16 count);
static void DoLoadSpritePalette(const u16 *src, u16 paletteOffset); static void DoLoadSpritePalette(const u16 *src, u16 paletteOffset);
static void obj_update_pos2(struct Sprite* sprite, s32 a1, s32 a2); static void UpdateSpriteMatrixAnchorPos(struct Sprite* sprite, s32 a1, s32 a2);
typedef void (*AnimFunc)(struct Sprite *); typedef void (*AnimFunc)(struct Sprite *);
typedef void (*AnimCmdFunc)(struct Sprite *); typedef void (*AnimCmdFunc)(struct Sprite *);
@ -99,13 +102,13 @@ typedef void (*AffineAnimCmdFunc)(u8 matrixNum, struct Sprite *);
#define DUMMY_OAM_DATA \ #define DUMMY_OAM_DATA \
{ \ { \
.y = 160, \ .y = DISPLAY_HEIGHT, \
.affineMode = 0, \ .affineMode = 0, \
.objMode = 0, \ .objMode = 0, \
.mosaic = 0, \ .mosaic = 0, \
.bpp = 0, \ .bpp = 0, \
.shape = SPRITE_SHAPE(8x8), \ .shape = SPRITE_SHAPE(8x8), \
.x = 304, \ .x = DISPLAY_WIDTH + 64, \
.matrixNum = 0, \ .matrixNum = 0, \
.size = SPRITE_SIZE(8x8), \ .size = SPRITE_SIZE(8x8), \
.tileNum = 0, \ .tileNum = 0, \
@ -159,41 +162,11 @@ static const struct Sprite sDummySprite =
{ {
.oam = DUMMY_OAM_DATA, .oam = DUMMY_OAM_DATA,
.anims = gDummySpriteAnimTable, .anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable, .affineAnims = gDummySpriteAffineAnimTable,
.template = &gDummySpriteTemplate, .template = &gDummySpriteTemplate,
.subspriteTables = NULL,
.callback = SpriteCallbackDummy, .callback = SpriteCallbackDummy,
.x = 304, .y = 160, .x = DISPLAY_WIDTH + 64,
.x2 = 0, .y2 = 0, .y = DISPLAY_HEIGHT,
.centerToCornerVecX = 0,
.centerToCornerVecY = 0,
.animNum = 0,
.animCmdIndex = 0,
.animDelayCounter = 0,
.animPaused = 0,
.affineAnimPaused = 0,
.animLoopCounter = 0,
.data = {0, 0, 0, 0, 0, 0, 0},
.inUse = 0,
.coordOffsetEnabled = 0,
.invisible = FALSE,
.flags_3 = 0,
.flags_4 = 0,
.flags_5 = 0,
.flags_6 = 0,
.flags_7 = 0,
.hFlip = 0,
.vFlip = 0,
.animBeginning = 0,
.affineAnimBeginning = 0,
.animEnded = 0,
.affineAnimEnded = 0,
.usingSheet = 0,
.flags_f = 0,
.sheetTileStart = 0,
.subspriteTableNum = 0,
.subspriteMode = 0,
.subpriority = 0xFF .subpriority = 0xFF
}; };
@ -890,16 +863,26 @@ void ResetAllSprites(void)
ResetSprite(&gSprites[i]); ResetSprite(&gSprites[i]);
} }
// UB: template pointer may point to freed temporary storage
void FreeSpriteTiles(struct Sprite *sprite) void FreeSpriteTiles(struct Sprite *sprite)
{ {
// UB: template pointer may point to freed temporary storage
#ifdef UBFIX
if (!sprite || !sprite->template)
return;
#endif
if (sprite->template->tileTag != TAG_NONE) if (sprite->template->tileTag != TAG_NONE)
FreeSpriteTilesByTag(sprite->template->tileTag); FreeSpriteTilesByTag(sprite->template->tileTag);
} }
// UB: template pointer may point to freed temporary storage
void FreeSpritePalette(struct Sprite *sprite) void FreeSpritePalette(struct Sprite *sprite)
{ {
// UB: template pointer may point to freed temporary storage
#ifdef UBFIX
if (!sprite || !sprite->template)
return;
#endif
FreeSpritePaletteByTag(sprite->template->paletteTag); FreeSpritePaletteByTag(sprite->template->paletteTag);
} }
@ -1098,8 +1081,8 @@ void BeginAffineAnim(struct Sprite *sprite)
sprite->affineAnimEnded = FALSE; sprite->affineAnimEnded = FALSE;
ApplyAffineAnimFrame(matrixNum, &frameCmd); ApplyAffineAnimFrame(matrixNum, &frameCmd);
sAffineAnimStates[matrixNum].delayCounter = frameCmd.duration; sAffineAnimStates[matrixNum].delayCounter = frameCmd.duration;
if (sprite->flags_f) if (sprite->anchored)
obj_update_pos2(sprite, sprite->data[6], sprite->data[7]); UpdateSpriteMatrixAnchorPos(sprite, sprite->sAnchorX, sprite->sAnchorY);
} }
} }
@ -1124,8 +1107,8 @@ void ContinueAffineAnim(struct Sprite *sprite)
funcIndex = type - 32765; funcIndex = type - 32765;
sAffineAnimCmdFuncs[funcIndex](matrixNum, sprite); sAffineAnimCmdFuncs[funcIndex](matrixNum, sprite);
} }
if (sprite->flags_f) if (sprite->anchored)
obj_update_pos2(sprite, sprite->data[6], sprite->data[7]); UpdateSpriteMatrixAnchorPos(sprite, sprite->sAnchorX, sprite->sAnchorY);
} }
} }
@ -1219,14 +1202,16 @@ u8 GetSpriteMatrixNum(struct Sprite *sprite)
return matrixNum; return matrixNum;
} }
void sub_8007E18(struct Sprite* sprite, s16 a2, s16 a3) // Used to shift a sprite's position as it scales.
// Only used by the minigame countdown, so that for instance the numbers don't slide up as they squish down before jumping.
void SetSpriteMatrixAnchor(struct Sprite* sprite, s16 x, s16 y)
{ {
sprite->data[6] = a2; sprite->sAnchorX = x;
sprite->data[7] = a3; sprite->sAnchorY = y;
sprite->flags_f = 1; sprite->anchored = TRUE;
} }
s32 sub_8007E28(s32 a0, s32 a1, s32 a2) static s32 GetAnchorCoord(s32 a0, s32 a1, s32 coord)
{ {
s32 subResult, var1; s32 subResult, var1;
@ -1235,27 +1220,27 @@ s32 sub_8007E28(s32 a0, s32 a1, s32 a2)
var1 = -(subResult) >> 9; var1 = -(subResult) >> 9;
else else
var1 = -(subResult >> 9); var1 = -(subResult >> 9);
return a2 - ((u32)(a2 * a1) / (u32)(a0) + var1); return coord - ((u32)(coord * a1) / (u32)(a0) + var1);
} }
void obj_update_pos2(struct Sprite *sprite, s32 a1, s32 a2) static void UpdateSpriteMatrixAnchorPos(struct Sprite *sprite, s32 x, s32 y)
{ {
s32 var0, var1, var2; s32 dimension, var1, var2;
u32 matrixNum = sprite->oam.matrixNum; u32 matrixNum = sprite->oam.matrixNum;
if (a1 != 0x800) if (x != NO_ANCHOR)
{ {
var0 = sOamDimensions32[sprite->oam.shape][sprite->oam.size].width; dimension = sOamDimensions32[sprite->oam.shape][sprite->oam.size].width;
var1 = var0 << 8; var1 = dimension << 8;
var2 = (var0 << 16) / gOamMatrices[matrixNum].a; var2 = (dimension << 16) / gOamMatrices[matrixNum].a;
sprite->x2 = sub_8007E28(var1, var2, a1); sprite->x2 = GetAnchorCoord(var1, var2, x);
} }
if (a2 != 0x800) if (y != NO_ANCHOR)
{ {
var0 = sOamDimensions32[sprite->oam.shape][sprite->oam.size].height; dimension = sOamDimensions32[sprite->oam.shape][sprite->oam.size].height;
var1 = var0 << 8; var1 = dimension << 8;
var2 = (var0 << 16) / gOamMatrices[matrixNum].d; var2 = (dimension << 16) / gOamMatrices[matrixNum].d;
sprite->y2 = sub_8007E28(var1, var2, a2); sprite->y2 = GetAnchorCoord(var1, var2, y);
} }
} }

View File

@ -5,6 +5,9 @@
#define SPRITE_NONE 0xFF #define SPRITE_NONE 0xFF
#define TAG_NONE 0xFFFF #define TAG_NONE 0xFFFF
// Given to SetSpriteMatrixAnchor to skip anchoring one of the coords.
#define NO_ANCHOR 0x800
struct SpriteSheet struct SpriteSheet
{ {
const void *data; // Raw uncompressed pixel data const void *data; // Raw uncompressed pixel data
@ -227,7 +230,7 @@ struct Sprite
bool16 animEnded:1; //0x10 bool16 animEnded:1; //0x10
bool16 affineAnimEnded:1; //0x20 bool16 affineAnimEnded:1; //0x20
bool16 usingSheet:1; //0x40 bool16 usingSheet:1; //0x40
bool16 flags_f:1; //0x80 bool16 anchored:1; //0x80
/*0x40*/ u16 sheetTileStart; /*0x40*/ u16 sheetTileStart;
@ -280,7 +283,7 @@ void FreeSpriteOamMatrix(struct Sprite *sprite);
void DestroySpriteAndFreeResources(struct Sprite *sprite); void DestroySpriteAndFreeResources(struct Sprite *sprite);
void sub_800142C(u32 a1, u32 a2, u16 *a3, u16 a4, u32 a5); void sub_800142C(u32 a1, u32 a2, u16 *a3, u16 a4, u32 a5);
void AnimateSprite(struct Sprite *sprite); void AnimateSprite(struct Sprite *sprite);
void sub_8007E18(struct Sprite* sprite, s16 a2, s16 a3); void SetSpriteMatrixAnchor(struct Sprite* sprite, s16 x, s16 y);
void StartSpriteAnim(struct Sprite *sprite, u8 animNum); void StartSpriteAnim(struct Sprite *sprite, u8 animNum);
void StartSpriteAnimIfDifferent(struct Sprite *sprite, u8 animNum); void StartSpriteAnimIfDifferent(struct Sprite *sprite, u8 animNum);
void SeekSpriteAnim(struct Sprite *sprite, u8 animCmdIndex); void SeekSpriteAnim(struct Sprite *sprite, u8 animCmdIndex);

View File

@ -82,6 +82,7 @@
#define MOVEMENT_TYPE_WALK_SLOWLY_IN_PLACE_UP 0x4E #define MOVEMENT_TYPE_WALK_SLOWLY_IN_PLACE_UP 0x4E
#define MOVEMENT_TYPE_WALK_SLOWLY_IN_PLACE_LEFT 0x4F #define MOVEMENT_TYPE_WALK_SLOWLY_IN_PLACE_LEFT 0x4F
#define MOVEMENT_TYPE_WALK_SLOWLY_IN_PLACE_RIGHT 0x50 #define MOVEMENT_TYPE_WALK_SLOWLY_IN_PLACE_RIGHT 0x50
#define NUM_MOVEMENT_TYPES 0x51
#define MOVEMENT_ACTION_FACE_DOWN 0x0 #define MOVEMENT_ACTION_FACE_DOWN 0x0
#define MOVEMENT_ACTION_FACE_UP 0x1 #define MOVEMENT_ACTION_FACE_UP 0x1
@ -318,4 +319,18 @@
#define ANIM_HOOKED_POKEMON_WEST 10 #define ANIM_HOOKED_POKEMON_WEST 10
#define ANIM_HOOKED_POKEMON_EAST 11 #define ANIM_HOOKED_POKEMON_EAST 11
// IDs for how NPCs that copy player movement should respond.
// Most go unused.
#define COPY_MOVE_NONE 0
#define COPY_MOVE_FACE 1
#define COPY_MOVE_WALK 2
#define COPY_MOVE_WALK_FAST 3
#define COPY_MOVE_WALK_FASTER 4
#define COPY_MOVE_SLIDE 5
#define COPY_MOVE_JUMP_IN_PLACE 6
#define COPY_MOVE_JUMP 7
#define COPY_MOVE_JUMP2 8
#define COPY_MOVE_EMPTY_1 9
#define COPY_MOVE_EMPTY_2 10
#endif // GUARD_CONSTANTS_EVENT_OBJECT_MOVEMENT_H #endif // GUARD_CONSTANTS_EVENT_OBJECT_MOVEMENT_H

View File

@ -127,8 +127,8 @@
#define MB_BRIDGE_OVER_POND_MED_EDGE_2 0x7B #define MB_BRIDGE_OVER_POND_MED_EDGE_2 0x7B
#define MB_BRIDGE_OVER_POND_HIGH_EDGE_1 0x7C #define MB_BRIDGE_OVER_POND_HIGH_EDGE_1 0x7C
#define MB_BRIDGE_OVER_POND_HIGH_EDGE_2 0x7D #define MB_BRIDGE_OVER_POND_HIGH_EDGE_2 0x7D
#define MB_UNUSED_BRIDGE_1 0x7E #define MB_UNUSED_BRIDGE 0x7E
#define MB_UNUSED_BRIDGE_2 0x7F #define MB_BIKE_BRIDGE_OVER_BARRIER 0x7F
#define MB_COUNTER 0x80 #define MB_COUNTER 0x80
#define MB_UNUSED_81 0x81 #define MB_UNUSED_81 0x81
#define MB_UNUSED_82 0x82 #define MB_UNUSED_82 0x82
@ -199,7 +199,7 @@
#define MB_HOLDS_LARGE_DECORATION 0xC3 #define MB_HOLDS_LARGE_DECORATION 0xC3
#define MB_SECRET_BASE_TV_SHIELD 0xC4 #define MB_SECRET_BASE_TV_SHIELD 0xC4
#define MB_PLAYER_ROOM_PC_ON 0xC5 #define MB_PLAYER_ROOM_PC_ON 0xC5
#define MB_C6 0xC6 #define MB_SECRET_BASE_DECORATION_BASE 0xC6
#define MB_SECRET_BASE_POSTER 0xC7 #define MB_SECRET_BASE_POSTER 0xC7
#define MB_UNUSED_C8 0xC8 #define MB_UNUSED_C8 0xC8
#define MB_UNUSED_C9 0xC9 #define MB_UNUSED_C9 0xC9

View File

@ -1,6 +1,8 @@
#ifndef GUARD_EVENT_OBJECT_MOVEMENT_H #ifndef GUARD_EVENT_OBJECT_MOVEMENT_H
#define GUARD_EVENT_OBJECT_MOVEMENT_H #define GUARD_EVENT_OBJECT_MOVEMENT_H
#include "constants/event_object_movement.h"
enum SpinnerRunnerFollowPatterns enum SpinnerRunnerFollowPatterns
{ {
RUNFOLLOW_ANY, RUNFOLLOW_ANY,
@ -395,13 +397,13 @@ u8 MovementType_CopyPlayer_Step1(struct ObjectEvent *, struct Sprite *);
u8 MovementType_CopyPlayer_Step2(struct ObjectEvent *, struct Sprite *); u8 MovementType_CopyPlayer_Step2(struct ObjectEvent *, struct Sprite *);
bool8 CopyablePlayerMovement_None(struct ObjectEvent *, struct Sprite *, u8, bool8(u8)); bool8 CopyablePlayerMovement_None(struct ObjectEvent *, struct Sprite *, u8, bool8(u8));
bool8 CopyablePlayerMovement_FaceDirection(struct ObjectEvent *, struct Sprite *, u8, bool8(u8)); bool8 CopyablePlayerMovement_FaceDirection(struct ObjectEvent *, struct Sprite *, u8, bool8(u8));
bool8 CopyablePlayerMovement_GoSpeed0(struct ObjectEvent *, struct Sprite *, u8, bool8(u8)); bool8 CopyablePlayerMovement_WalkNormal(struct ObjectEvent *, struct Sprite *, u8, bool8(u8));
bool8 CopyablePlayerMovement_GoSpeed1(struct ObjectEvent *, struct Sprite *, u8, bool8(u8)); bool8 CopyablePlayerMovement_WalkFast(struct ObjectEvent *, struct Sprite *, u8, bool8(u8));
bool8 CopyablePlayerMovement_GoSpeed2(struct ObjectEvent *, struct Sprite *, u8, bool8(u8)); bool8 CopyablePlayerMovement_WalkFaster(struct ObjectEvent *, struct Sprite *, u8, bool8(u8));
bool8 CopyablePlayerMovement_Slide(struct ObjectEvent *, struct Sprite *, u8, bool8(u8)); bool8 CopyablePlayerMovement_Slide(struct ObjectEvent *, struct Sprite *, u8, bool8(u8));
bool8 cph_IM_DIFFERENT(struct ObjectEvent *, struct Sprite *, u8, bool8(u8)); bool8 CopyablePlayerMovement_JumpInPlace(struct ObjectEvent *, struct Sprite *, u8, bool8(u8));
bool8 CopyablePlayerMovement_GoSpeed4(struct ObjectEvent *, struct Sprite *, u8, bool8(u8));
bool8 CopyablePlayerMovement_Jump(struct ObjectEvent *, struct Sprite *, u8, bool8(u8)); bool8 CopyablePlayerMovement_Jump(struct ObjectEvent *, struct Sprite *, u8, bool8(u8));
bool8 CopyablePlayerMovement_Jump2(struct ObjectEvent *, struct Sprite *, u8, bool8(u8));
u8 MovementType_CopyPlayerInGrass_Step1(struct ObjectEvent *, struct Sprite *); u8 MovementType_CopyPlayerInGrass_Step1(struct ObjectEvent *, struct Sprite *);
u8 MovementType_Buried_Step0(struct ObjectEvent *, struct Sprite *); u8 MovementType_Buried_Step0(struct ObjectEvent *, struct Sprite *);
u8 MovementType_WalkInPlace_Step0(struct ObjectEvent *, struct Sprite *); u8 MovementType_WalkInPlace_Step0(struct ObjectEvent *, struct Sprite *);

View File

@ -147,7 +147,7 @@ void SetNextWeather(u8 weather);
void SetCurrentAndNextWeather(u8 weather); void SetCurrentAndNextWeather(u8 weather);
void SetCurrentAndNextWeatherNoDelay(u8 weather); void SetCurrentAndNextWeatherNoDelay(u8 weather);
void ApplyWeatherGammaShiftIfIdle(s8 gammaIndex); void ApplyWeatherGammaShiftIfIdle(s8 gammaIndex);
void sub_80ABC7C(u8 gammaIndex, u8 gammaTargetIndex, u8 gammaStepDelay); void ApplyWeatherGammaShiftIfIdle_Gradual(u8 gammaIndex, u8 gammaTargetIndex, u8 gammaStepDelay);
void FadeScreen(u8 mode, s8 delay); void FadeScreen(u8 mode, s8 delay);
bool8 IsWeatherNotFadingIn(void); bool8 IsWeatherNotFadingIn(void);
void UpdateSpritePaletteWithWeather(u8 spritePaletteIndex); void UpdateSpritePaletteWithWeather(u8 spritePaletteIndex);

View File

@ -211,7 +211,7 @@ struct ObjectEvent
/*0x1F*/ u8 previousMetatileBehavior; /*0x1F*/ u8 previousMetatileBehavior;
/*0x20*/ u8 previousMovementDirection; /*0x20*/ u8 previousMovementDirection;
/*0x21*/ u8 directionSequenceIndex; /*0x21*/ u8 directionSequenceIndex;
/*0x22*/ u8 playerCopyableMovement; /*0x22*/ u8 playerCopyableMovement; // COPY_MOVE_*
/*size = 0x24*/ /*size = 0x24*/
}; };

View File

@ -19,6 +19,6 @@ void PadNameString(u8 *dest, u8 padChar);
void ConvertInternationalPlayerNameStripChar(u8 *, u8); void ConvertInternationalPlayerNameStripChar(u8 *, u8);
void ConvertInternationalContestantName(u8 *); void ConvertInternationalContestantName(u8 *);
int GetNicknameLanguage(u8 *); int GetNicknameLanguage(u8 *);
void sub_81DB620(int windowId, int columnStart, int rowStart, int numFillTiles, int numRows); void FillWindowTilesByRow(int windowId, int columnStart, int rowStart, int numFillTiles, int numRows);
#endif // GUARD_INTERNATIONAL_STRING_UTIL_H #endif // GUARD_INTERNATIONAL_STRING_UTIL_H

View File

@ -5,6 +5,7 @@
#define MAX_RFU_PLAYERS 5 #define MAX_RFU_PLAYERS 5
#define CMD_LENGTH 8 #define CMD_LENGTH 8
#define QUEUE_CAPACITY 50 #define QUEUE_CAPACITY 50
#define OVERWORLD_RECV_QUEUE_MAX 3
#define BLOCK_BUFFER_SIZE 0x100 #define BLOCK_BUFFER_SIZE 0x100
#define LINK_SLAVE 0 #define LINK_SLAVE 0
@ -301,7 +302,7 @@ bool32 Link_AnyPartnersPlayingFRLG_JP(void);
void ResetLinkPlayerCount(void); void ResetLinkPlayerCount(void);
void SaveLinkPlayers(u8 a0); void SaveLinkPlayers(u8 a0);
void SetWirelessCommType0(void); void SetWirelessCommType0(void);
bool32 IsLinkRecvQueueLengthAtLeast3(void); bool32 IsLinkRecvQueueAtOverworldMax(void);
extern u16 gLinkPartnersHeldKeys[6]; extern u16 gLinkPartnersHeldKeys[6];
extern u32 gLinkDebugSeed; extern u32 gLinkDebugSeed;

View File

@ -27,8 +27,8 @@ u8 GetLRKeysPressed(void);
u8 GetLRKeysPressedAndHeld(void); u8 GetLRKeysPressedAndHeld(void);
bool8 IsHoldingItemAllowed(u16 itemId); bool8 IsHoldingItemAllowed(u16 itemId);
bool8 IsWritingMailAllowed(u16 itemId); bool8 IsWritingMailAllowed(u16 itemId);
bool8 MenuHelpers_LinkSomething(void); bool8 MenuHelpers_IsLinkActive(void);
bool8 MenuHelpers_CallLinkSomething(void); bool8 MenuHelpers_ShouldWaitForLinkRecv(void);
void SetItemListPerPageCount(struct ItemSlot *slots, u8 slotsCount, u8 *pageItems, u8 *totalItems, u8 maxPerPage); void SetItemListPerPageCount(struct ItemSlot *slots, u8 slotsCount, u8 *pageItems, u8 *totalItems, u8 maxPerPage);
void SetCursorWithinListBounds(u16 *scrollOffset, u16 *cursorPos, u8 maxShownItems, u8 totalItems); void SetCursorWithinListBounds(u16 *scrollOffset, u16 *cursorPos, u8 maxShownItems, u8 totalItems);
void SetCursorScrollWithinListBounds(u16 *scrollOffset, u16 *cursorPos, u8 shownItems, u8 totalItems, u8 maxShownItems); void SetCursorScrollWithinListBounds(u16 *scrollOffset, u16 *cursorPos, u8 shownItems, u8 totalItems, u8 maxShownItems);

View File

@ -23,7 +23,6 @@ bool8 MetatileBehavior_IsIce(u8);
bool8 MetatileBehavior_IsWarpDoor(u8); bool8 MetatileBehavior_IsWarpDoor(u8);
bool8 MetatileBehavior_IsDoor(u8); bool8 MetatileBehavior_IsDoor(u8);
bool8 MetatileBehavior_IsEscalator(u8); bool8 MetatileBehavior_IsEscalator(u8);
bool8 MetatileBehavior_IsMB_04(u8);
bool8 MetatileBehavior_IsLadder(u8); bool8 MetatileBehavior_IsLadder(u8);
bool8 MetatileBehavior_IsNonAnimDoor(u8); bool8 MetatileBehavior_IsNonAnimDoor(u8);
bool8 MetatileBehavior_IsDeepSouthWarp(u8); bool8 MetatileBehavior_IsDeepSouthWarp(u8);
@ -36,7 +35,6 @@ bool8 MetatileBehavior_IsArrowWarp(u8);
bool8 MetatileBehavior_IsForcedMovementTile(u8); bool8 MetatileBehavior_IsForcedMovementTile(u8);
bool8 MetatileBehavior_IsIce_2(u8); bool8 MetatileBehavior_IsIce_2(u8);
bool8 MetatileBehavior_IsTrickHouseSlipperyFloor(u8); bool8 MetatileBehavior_IsTrickHouseSlipperyFloor(u8);
bool8 MetatileBehavior_IsMB_05(u8);
bool8 MetatileBehavior_IsWalkNorth(u8); bool8 MetatileBehavior_IsWalkNorth(u8);
bool8 MetatileBehavior_IsWalkSouth(u8); bool8 MetatileBehavior_IsWalkSouth(u8);
bool8 MetatileBehavior_IsWalkWest(u8); bool8 MetatileBehavior_IsWalkWest(u8);
@ -59,14 +57,12 @@ bool8 MetatileBehavior_IsSecretBaseTree(u8);
bool8 MetatileBehavior_IsSecretBaseShrub(u8); bool8 MetatileBehavior_IsSecretBaseShrub(u8);
bool8 MetatileBehavior_IsSecretBasePC(u8); bool8 MetatileBehavior_IsSecretBasePC(u8);
bool8 MetatileBehavior_IsRecordMixingSecretBasePC(u8); bool8 MetatileBehavior_IsRecordMixingSecretBasePC(u8);
bool8 MetatileBehavior_IsMB_B2(u8);
bool8 MetatileBehavior_IsBlockDecoration(u8); bool8 MetatileBehavior_IsBlockDecoration(u8);
bool8 MetatileBehavior_IsSecretBaseImpassable(u8); bool8 MetatileBehavior_IsSecretBaseImpassable(u8);
bool8 MetatileBehavior_IsMB_C6(u8); bool8 MetatileBehavior_IsSecretBaseDecorationBase(u8);
bool8 MetatileBehavior_IsSecretBasePoster(u8); bool8 MetatileBehavior_IsSecretBasePoster(u8);
bool8 MetatileBehavior_IsNormal(u8); bool8 MetatileBehavior_IsNormal(u8);
bool8 MetatileBehavior_IsSecretBaseNorthWall(u8); bool8 MetatileBehavior_IsSecretBaseNorthWall(u8);
bool8 MetatileBehavior_IsMB_B2_Duplicate(u8);
bool8 MetatileBehavior_HoldsSmallDecoration(u8); bool8 MetatileBehavior_HoldsSmallDecoration(u8);
bool8 MetatileBehavior_HoldsLargeDecoration(u8); bool8 MetatileBehavior_HoldsLargeDecoration(u8);
bool8 MetatileBehavior_IsSecretBaseHole(u8); bool8 MetatileBehavior_IsSecretBaseHole(u8);
@ -97,7 +93,6 @@ bool8 MetatileBehavior_IsShallowFlowingWater(u8);
bool8 MetatileBehavior_IsThinIce(u8); bool8 MetatileBehavior_IsThinIce(u8);
bool8 MetatileBehavior_IsCrackedIce(u8); bool8 MetatileBehavior_IsCrackedIce(u8);
bool8 MetatileBehavior_IsDeepOrOceanWater(u8); bool8 MetatileBehavior_IsDeepOrOceanWater(u8);
bool8 MetatileBehavior_IsMB_18_OrMB_1A(u8);
bool8 MetatileBehavior_IsSurfableAndNotWaterfall(u8); bool8 MetatileBehavior_IsSurfableAndNotWaterfall(u8);
bool8 MetatileBehavior_IsEastBlocked(u8); bool8 MetatileBehavior_IsEastBlocked(u8);
bool8 MetatileBehavior_IsWestBlocked(u8); bool8 MetatileBehavior_IsWestBlocked(u8);
@ -123,7 +118,7 @@ bool8 MetatileBehavior_IsSecretBaseSpinMat(u8);
bool8 MetatileBehavior_IsLavaridgeB1FWarp(u8); bool8 MetatileBehavior_IsLavaridgeB1FWarp(u8);
bool8 MetatileBehavior_IsLavaridge1FWarp(u8); bool8 MetatileBehavior_IsLavaridge1FWarp(u8);
bool8 MetatileBehavior_IsAquaHideoutWarp(u8); bool8 MetatileBehavior_IsAquaHideoutWarp(u8);
bool8 MetatileBehavior_IsBridgeOverOcean(u8); bool8 MetatileBehavior_IsUnionRoomWarp(u8);
bool8 MetatileBehavior_IsMossdeepGymWarp(u8); bool8 MetatileBehavior_IsMossdeepGymWarp(u8);
bool8 MetatileBehavior_IsSurfableFishableWater(u8); bool8 MetatileBehavior_IsSurfableFishableWater(u8);
bool8 MetatileBehavior_IsMtPyreHole(u8); bool8 MetatileBehavior_IsMtPyreHole(u8);

View File

@ -127,7 +127,7 @@ u8 GetSavedWarpRegionMapSectionId(void);
u8 GetCurrentRegionMapSectionId(void); u8 GetCurrentRegionMapSectionId(void);
u8 GetCurrentMapBattleScene(void); u8 GetCurrentMapBattleScene(void);
void CleanupOverworldWindowsAndTilemaps(void); void CleanupOverworldWindowsAndTilemaps(void);
bool32 IsUpdateLinkStateCBActive(void); bool32 IsOverworldLinkActive(void);
void CB1_Overworld(void); void CB1_Overworld(void);
void CB2_OverworldBasic(void); void CB2_OverworldBasic(void);
void CB2_Overworld(void); void CB2_Overworld(void);
@ -151,7 +151,7 @@ u16 SetInCableClubSeat(void);
u16 SetLinkWaitingForScript(void); u16 SetLinkWaitingForScript(void);
u16 QueueExitLinkRoomKey(void); u16 QueueExitLinkRoomKey(void);
u16 SetStartedCableClubActivity(void); u16 SetStartedCableClubActivity(void);
bool32 Overworld_LinkRecvQueueLengthMoreThan2(void); bool32 Overworld_IsRecvQueueAtMax(void);
bool32 Overworld_RecvKeysFromLinkIsRunning(void); bool32 Overworld_RecvKeysFromLinkIsRunning(void);
bool32 Overworld_SendKeysToLinkIsRunning(void); bool32 Overworld_SendKeysToLinkIsRunning(void);
bool32 IsSendingKeysOverCable(void); bool32 IsSendingKeysOverCable(void);

View File

@ -72,7 +72,7 @@ void MarkUsedPulseBlendPalettes(struct PulseBlend *, u16, u8);
void UnloadUsedPulseBlendPalettes(struct PulseBlend *, u16, u8); void UnloadUsedPulseBlendPalettes(struct PulseBlend *, u16, u8);
void UnmarkUsedPulseBlendPalettes(struct PulseBlend *, u16, u8); void UnmarkUsedPulseBlendPalettes(struct PulseBlend *, u16, u8);
void UpdatePulseBlend(struct PulseBlend *); void UpdatePulseBlend(struct PulseBlend *);
void ClearTilemapRect(u16 *dest, u16 src, u8 left, u8 top, u8 width, u8 height); void FillTilemapRect(u16 *dest, u16 src, u8 left, u8 top, u8 width, u8 height);
void SetTilemapRect(u16 *dest, u16 *src, u8 left, u8 top, u8 width, u8 height); void SetTilemapRect(u16 *dest, u16 *src, u8 left, u8 top, u8 width, u8 height);
void RouletteFlash_Run(struct RouletteFlashUtil *r0); void RouletteFlash_Run(struct RouletteFlashUtil *r0);
void RouletteFlash_Reset(struct RouletteFlashUtil *r0); void RouletteFlash_Reset(struct RouletteFlashUtil *r0);

View File

@ -14,14 +14,14 @@ extern const u16 gTextWindowFrame1_Pal[];
const struct TilesPal *GetWindowFrameTilesPal(u8 id); const struct TilesPal *GetWindowFrameTilesPal(u8 id);
void LoadMessageBoxGfx(u8 windowId, u16 destOffset, u8 palOffset); void LoadMessageBoxGfx(u8 windowId, u16 destOffset, u8 palOffset);
void LoadUserWindowBorderGfx(u8 windowId, u16 destOffset, u8 palOffset);
void LoadWindowGfx(u8 windowId, u8 frameId, u16 destOffset, u8 palOffset); void LoadWindowGfx(u8 windowId, u8 frameId, u16 destOffset, u8 palOffset);
void LoadUserWindowBorderGfx(u8 windowId, u16 destOffset, u8 palOffset);
void LoadUserWindowBorderGfx_(u8 windowId, u16 destOffset, u8 palOffset); void LoadUserWindowBorderGfx_(u8 windowId, u16 destOffset, u8 palOffset);
void LoadUserWindowBorderGfxOnBg(u8 bg, u16 destOffset, u8 palOffset);
void DrawTextBorderOuter(u8 windowId, u16 tileNum, u8 palNum); void DrawTextBorderOuter(u8 windowId, u16 tileNum, u8 palNum);
void DrawTextBorderInner(u8 windowId, u16 tileNum, u8 palNum); void DrawTextBorderInner(u8 windowId, u16 tileNum, u8 palNum);
void rbox_fill_rectangle(u8 windowId); void rbox_fill_rectangle(u8 windowId);
const u16 *GetTextWindowPalette(u8 id); const u16 *GetTextWindowPalette(u8 id);
const u16 *GetOverworldTextboxPalettePtr(void); const u16 *GetOverworldTextboxPalettePtr(void);
void sub_8098C6C(u8 bg, u16 destOffset, u8 palOffset);
#endif // GUARD_TEXT_WINDOW_H #endif // GUARD_TEXT_WINDOW_H

View File

@ -104,7 +104,7 @@ static void HblankCb_TourneyTree(void);
static void VblankCb_TourneyTree(void); static void VblankCb_TourneyTree(void);
static u8 UpdateTourneyTreeCursor(u8 taskId); static u8 UpdateTourneyTreeCursor(u8 taskId);
static void DecideRoundWinners(u8 roundId); static void DecideRoundWinners(u8 roundId);
static u8 sub_81953E8(u8 tournamentId, u8); static u8 GetOpposingNPCTournamentIdByRound(u8 tournamentId, u8);
static void DrawTourneyAdvancementLine(u8, u8); static void DrawTourneyAdvancementLine(u8, u8);
static void SpriteCb_HorizontalScrollArrow(struct Sprite *sprite); static void SpriteCb_HorizontalScrollArrow(struct Sprite *sprite);
static void SpriteCb_VerticalScrollArrow(struct Sprite *sprite); static void SpriteCb_VerticalScrollArrow(struct Sprite *sprite);
@ -1197,7 +1197,7 @@ static const u8 sLastMatchCardNum[DOME_ROUNDS_COUNT] =
[DOME_FINAL] = 30 [DOME_FINAL] = 30
}; };
static const u8 gUnknown_0860D1A0[DOME_TOURNAMENT_TRAINERS_COUNT / 2][DOME_ROUNDS_COUNT] = static const u8 sTrainerAndRoundToLastMatchCardNum[DOME_TOURNAMENT_TRAINERS_COUNT / 2][DOME_ROUNDS_COUNT] =
{ {
{16, 24, 28, 30}, {16, 24, 28, 30},
{17, 24, 28, 30}, {17, 24, 28, 30},
@ -1209,7 +1209,7 @@ static const u8 gUnknown_0860D1A0[DOME_TOURNAMENT_TRAINERS_COUNT / 2][DOME_ROUND
{23, 27, 29, 30}, {23, 27, 29, 30},
}; };
static const u8 gUnknown_0860D1C0[DOME_TOURNAMENT_TRAINERS_COUNT] = {0, 15, 8, 7, 3, 12, 11, 4, 1, 14, 9, 6, 2, 13, 10, 5}; static const u8 sTournamentIdToPairedTrainerIds[DOME_TOURNAMENT_TRAINERS_COUNT] = {0, 15, 8, 7, 3, 12, 11, 4, 1, 14, 9, 6, 2, 13, 10, 5};
// The first line of text on a trainers info card. It describes their potential to win, based on their seed in the tournament tree. // The first line of text on a trainers info card. It describes their potential to win, based on their seed in the tournament tree.
// Dome Ace Tucker has their own separate potential text. // Dome Ace Tucker has their own separate potential text.
@ -4178,7 +4178,7 @@ static u8 Task_GetInfoCardInput(u8 taskId)
if (input == INFOCARD_INPUT_AB) if (input == INFOCARD_INPUT_AB)
{ {
if (sInfoCard->pos != 0) if (sInfoCard->pos != 0)
gTasks[taskId2].data[1] = gUnknown_0860D1A0[position / 2][sInfoCard->pos - 1]; gTasks[taskId2].data[1] = sTrainerAndRoundToLastMatchCardNum[position / 2][sInfoCard->pos - 1];
else else
gTasks[taskId2].data[1] = position; gTasks[taskId2].data[1] = position;
} }
@ -4218,9 +4218,9 @@ static u8 Task_GetInfoCardInput(u8 taskId)
if (input == INFOCARD_INPUT_AB) if (input == INFOCARD_INPUT_AB)
{ {
if (sInfoCard->pos == 0) // On left trainer info card if (sInfoCard->pos == 0) // On left trainer info card
gTasks[taskId2].data[1] = gUnknown_0860D1C0[sInfoCard->tournamentIds[0]]; gTasks[taskId2].data[1] = sTournamentIdToPairedTrainerIds[sInfoCard->tournamentIds[0]];
else if (sInfoCard->pos == 2) // On right trainer info card else if (sInfoCard->pos == 2) // On right trainer info card
gTasks[taskId2].data[1] = gUnknown_0860D1C0[sInfoCard->tournamentIds[1]]; gTasks[taskId2].data[1] = sTournamentIdToPairedTrainerIds[sInfoCard->tournamentIds[1]];
else // On match info card else // On match info card
gTasks[taskId2].data[1] = position; gTasks[taskId2].data[1] = position;
} }
@ -5224,7 +5224,7 @@ static u16 GetWinningMove(int winnerTournamentId, int loserTournamentId, u8 roun
{ {
for (i = 0; i < roundId - 1; i++) for (i = 0; i < roundId - 1; i++)
{ {
if (gSaveBlock2Ptr->frontier.domeWinningMoves[sub_81953E8(winnerTournamentId, i)] == moveIds[j]) if (gSaveBlock2Ptr->frontier.domeWinningMoves[GetOpposingNPCTournamentIdByRound(winnerTournamentId, i)] == moveIds[j])
break; break;
} }
if (i != roundId - 1) if (i != roundId - 1)
@ -5934,10 +5934,10 @@ int TrainerIdToDomeTournamentId(u16 trainerId)
return i; return i;
} }
static u8 sub_81953E8(u8 tournamentId, u8 round) static u8 GetOpposingNPCTournamentIdByRound(u8 tournamentId, u8 round)
{ {
u8 tournamentIds[2]; u8 tournamentIds[2];
BufferDomeWinString(gUnknown_0860D1A0[gUnknown_0860D1C0[tournamentId] / 2][round] - 16, tournamentIds); BufferDomeWinString(sTrainerAndRoundToLastMatchCardNum[sTournamentIdToPairedTrainerIds[tournamentId] / 2][round] - 16, tournamentIds);
if (tournamentId == tournamentIds[0]) if (tournamentId == tournamentIds[0])
return tournamentIds[1]; return tournamentIds[1];
else else

View File

@ -452,9 +452,9 @@ static void VBlankCB_PyramidBag(void)
static void CB2_LoadPyramidBagMenu(void) static void CB2_LoadPyramidBagMenu(void)
{ {
while (MenuHelpers_CallLinkSomething() != TRUE while (MenuHelpers_ShouldWaitForLinkRecv() != TRUE
&& LoadPyramidBagMenu() != TRUE && LoadPyramidBagMenu() != TRUE
&& MenuHelpers_LinkSomething() != TRUE); && MenuHelpers_IsLinkActive() != TRUE);
} }
static bool8 LoadPyramidBagMenu(void) static bool8 LoadPyramidBagMenu(void)
@ -484,7 +484,7 @@ static bool8 LoadPyramidBagMenu(void)
gMain.state++; gMain.state++;
break; break;
case 5: case 5:
if (!MenuHelpers_LinkSomething()) if (!MenuHelpers_IsLinkActive())
ResetTasks(); ResetTasks();
gMain.state++; gMain.state++;
break; break;
@ -885,7 +885,7 @@ static void Task_ClosePyramidBag(u8 taskId)
static void Task_HandlePyramidBagInput(u8 taskId) static void Task_HandlePyramidBagInput(u8 taskId)
{ {
s16 *data = gTasks[taskId].data; s16 *data = gTasks[taskId].data;
if (MenuHelpers_CallLinkSomething() == TRUE || gPaletteFade.active) if (MenuHelpers_ShouldWaitForLinkRecv() == TRUE || gPaletteFade.active)
return; return;
if (JOY_NEW(SELECT_BUTTON)) if (JOY_NEW(SELECT_BUTTON))
@ -990,7 +990,7 @@ static void PrintMenuActionText_MultiRow(u8 windowId, u8 horizontalCount, u8 ver
static void HandleMenuActionInput_SingleRow(u8 taskId) static void HandleMenuActionInput_SingleRow(u8 taskId)
{ {
if (MenuHelpers_CallLinkSomething() != TRUE) if (MenuHelpers_ShouldWaitForLinkRecv() != TRUE)
{ {
s32 id = Menu_ProcessInputNoWrap(); s32 id = Menu_ProcessInputNoWrap();
switch (id) switch (id)
@ -1012,7 +1012,7 @@ static void HandleMenuActionInput_SingleRow(u8 taskId)
static void HandleMenuActionInput_2x2(u8 taskId) static void HandleMenuActionInput_2x2(u8 taskId)
{ {
if (MenuHelpers_CallLinkSomething() != TRUE) if (MenuHelpers_ShouldWaitForLinkRecv() != TRUE)
{ {
s8 id = Menu_GetCursorPos(); s8 id = Menu_GetCursorPos();
if (JOY_NEW(DPAD_UP)) if (JOY_NEW(DPAD_UP))
@ -1325,7 +1325,7 @@ static void Task_BeginItemSwap(u8 taskId)
static void Task_ItemSwapHandleInput(u8 taskId) static void Task_ItemSwapHandleInput(u8 taskId)
{ {
s16 *data = gTasks[taskId].data; s16 *data = gTasks[taskId].data;
if (MenuHelpers_CallLinkSomething() != TRUE) if (MenuHelpers_ShouldWaitForLinkRecv() != TRUE)
{ {
if (JOY_NEW(SELECT_BUTTON)) if (JOY_NEW(SELECT_BUTTON))
{ {

View File

@ -200,11 +200,11 @@ static void CB2_InitBerryTagScreen(void)
{ {
while (1) while (1)
{ {
if (MenuHelpers_CallLinkSomething() == TRUE) if (MenuHelpers_ShouldWaitForLinkRecv() == TRUE)
break; break;
if (InitBerryTagScreen() == TRUE) if (InitBerryTagScreen() == TRUE)
break; break;
if (MenuHelpers_LinkSomething() == TRUE) if (MenuHelpers_IsLinkActive() == TRUE)
break; break;
} }
} }
@ -237,7 +237,7 @@ static bool8 InitBerryTagScreen(void)
gMain.state++; gMain.state++;
break; break;
case 5: case 5:
if (!MenuHelpers_LinkSomething()) if (!MenuHelpers_IsLinkActive())
ResetTasks(); ResetTasks();
gMain.state++; gMain.state++;
break; break;

View File

@ -658,7 +658,7 @@ static void AcroBikeTransition_SideJump(u8 direction)
playerObjEvent = &gObjectEvents[gPlayerAvatar.objectEventId]; playerObjEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
PlaySE(SE_BIKE_HOP); PlaySE(SE_BIKE_HOP);
playerObjEvent->facingDirectionLocked = 1; playerObjEvent->facingDirectionLocked = 1;
PlayerSetAnimId(GetJumpMovementAction(direction), 2); PlayerSetAnimId(GetJumpMovementAction(direction), COPY_MOVE_WALK);
} }
static void AcroBikeTransition_TurnJump(u8 direction) static void AcroBikeTransition_TurnJump(u8 direction)

View File

@ -10,43 +10,6 @@ static EWRAM_DATA struct
struct ConfettiUtil *array; struct ConfettiUtil *array;
} *sWork = NULL; } *sWork = NULL;
static void sub_81520A8(void *dest, u16 value, u8 left, u8 top, u8 width, u8 height) // Unused.
{
u8 i;
u8 j;
u8 x;
u8 y;
for (i = 0, y = top; i < height; i++)
{
for (x = left, j = 0; j < width; j++)
{
*(u16 *)((dest) + (y * 64 + x * 2)) = value;
x = (x + 1) % 32;
}
y = (y + 1) % 32;
}
}
static void sub_8152134(void *dest, const u16 *src, u8 left, u8 top, u8 width, u8 height) // Unused.
{
u8 i;
u8 j;
u8 x;
u8 y;
const u16 *_src;
for (i = 0, _src = src, y = top; i < height; i++)
{
for (x = left, j = 0; j < width; j++)
{
*(u16 *)((dest) + (y * 64 + x * 2)) = *(_src++);
x = (x + 1) % 32;
}
y = (y + 1) % 32;
}
}
bool32 ConfettiUtil_Init(u8 count) bool32 ConfettiUtil_Init(u8 count)
{ {
u8 i = 0; u8 i = 0;

View File

@ -388,17 +388,17 @@ u8 (*const gMovementTypeFuncs_CopyPlayer[])(struct ObjectEvent *, struct Sprite
}; };
bool8 (*const gCopyPlayerMovementFuncs[])(struct ObjectEvent *, struct Sprite *, u8, bool8(u8)) = { bool8 (*const gCopyPlayerMovementFuncs[])(struct ObjectEvent *, struct Sprite *, u8, bool8(u8)) = {
CopyablePlayerMovement_None, [COPY_MOVE_NONE] = CopyablePlayerMovement_None,
CopyablePlayerMovement_FaceDirection, [COPY_MOVE_FACE] = CopyablePlayerMovement_FaceDirection,
CopyablePlayerMovement_GoSpeed0, [COPY_MOVE_WALK] = CopyablePlayerMovement_WalkNormal,
CopyablePlayerMovement_GoSpeed1, [COPY_MOVE_WALK_FAST] = CopyablePlayerMovement_WalkFast,
CopyablePlayerMovement_GoSpeed2, [COPY_MOVE_WALK_FASTER] = CopyablePlayerMovement_WalkFaster,
CopyablePlayerMovement_Slide, [COPY_MOVE_SLIDE] = CopyablePlayerMovement_Slide,
cph_IM_DIFFERENT, [COPY_MOVE_JUMP_IN_PLACE] = CopyablePlayerMovement_JumpInPlace,
CopyablePlayerMovement_GoSpeed4, [COPY_MOVE_JUMP] = CopyablePlayerMovement_Jump,
CopyablePlayerMovement_Jump, [COPY_MOVE_JUMP2] = CopyablePlayerMovement_Jump2,
CopyablePlayerMovement_None, [COPY_MOVE_EMPTY_1] = CopyablePlayerMovement_None,
CopyablePlayerMovement_None, [COPY_MOVE_EMPTY_2] = CopyablePlayerMovement_None,
}; };
u8 (*const gMovementTypeFuncs_CopyPlayerInGrass[])(struct ObjectEvent *, struct Sprite *) = { u8 (*const gMovementTypeFuncs_CopyPlayerInGrass[])(struct ObjectEvent *, struct Sprite *) = {

View File

@ -113,7 +113,7 @@ void Unused_LZDecompressWramIndirect(const void **src, void *dest)
LZ77UnCompWram(*src, dest); LZ77UnCompWram(*src, dest);
} }
void sub_803471C(s32 object_size, s32 object_count, u8 *src_tiles, u8 *dest_tiles) static void StitchObjectsOn8x8Canvas(s32 object_size, s32 object_count, u8 *src_tiles, u8 *dest_tiles)
{ {
/* /*
This function appears to emulate behaviour found in the GB(C) versions regarding how the Pokemon images This function appears to emulate behaviour found in the GB(C) versions regarding how the Pokemon images

View File

@ -1310,7 +1310,7 @@ static void StartEasyChatScreen(u8 taskId, TaskFunc taskFunc)
static void Task_InitEasyChatScreen(u8 taskId) static void Task_InitEasyChatScreen(u8 taskId)
{ {
if (!IsUpdateLinkStateCBActive()) if (!IsOverworldLinkActive())
{ {
while (InitEasyChatScreen(taskId)); while (InitEasyChatScreen(taskId));
} }

File diff suppressed because it is too large Load Diff

View File

@ -421,7 +421,7 @@ static const u8 *GetInteractedMetatileScript(struct MapPosition *position, u8 me
return SecretBase_EventScript_SandOrnament; return SecretBase_EventScript_SandOrnament;
if (MetatileBehavior_IsSecretBaseShieldOrToyTV(metatileBehavior) == TRUE) if (MetatileBehavior_IsSecretBaseShieldOrToyTV(metatileBehavior) == TRUE)
return SecretBase_EventScript_ShieldOrToyTV; return SecretBase_EventScript_ShieldOrToyTV;
if (MetatileBehavior_IsMB_C6(metatileBehavior) == TRUE) if (MetatileBehavior_IsSecretBaseDecorationBase(metatileBehavior) == TRUE)
{ {
CheckInteractedWithFriendsFurnitureBottom(); CheckInteractedWithFriendsFurnitureBottom();
return NULL; return NULL;
@ -729,9 +729,8 @@ static bool8 TryStartWarpEventScript(struct MapPosition *position, u16 metatileB
DoTeleportTileWarp(); DoTeleportTileWarp();
return TRUE; return TRUE;
} }
if (MetatileBehavior_IsBridgeOverOcean(metatileBehavior) == TRUE) if (MetatileBehavior_IsUnionRoomWarp(metatileBehavior) == TRUE)
{ {
// Maybe unused? This MB is used by log bridges, but there's never a warp event on them.
DoSpinExitWarp(); DoSpinExitWarp();
return TRUE; return TRUE;
} }
@ -762,7 +761,7 @@ static bool8 IsWarpMetatileBehavior(u16 metatileBehavior)
&& MetatileBehavior_IsAquaHideoutWarp(metatileBehavior) != TRUE && MetatileBehavior_IsAquaHideoutWarp(metatileBehavior) != TRUE
&& MetatileBehavior_IsMtPyreHole(metatileBehavior) != TRUE && MetatileBehavior_IsMtPyreHole(metatileBehavior) != TRUE
&& MetatileBehavior_IsMossdeepGymWarp(metatileBehavior) != TRUE && MetatileBehavior_IsMossdeepGymWarp(metatileBehavior) != TRUE
&& MetatileBehavior_IsBridgeOverOcean(metatileBehavior) != TRUE) && MetatileBehavior_IsUnionRoomWarp(metatileBehavior) != TRUE)
return FALSE; return FALSE;
return TRUE; return TRUE;
} }

View File

@ -225,10 +225,10 @@ static void (*const sPlayerAvatarTransitionFuncs[])(struct ObjectEvent *) =
static bool8 (*const sArrowWarpMetatileBehaviorChecks[])(u8) = static bool8 (*const sArrowWarpMetatileBehaviorChecks[])(u8) =
{ {
MetatileBehavior_IsSouthArrowWarp, [DIR_SOUTH - 1] = MetatileBehavior_IsSouthArrowWarp,
MetatileBehavior_IsNorthArrowWarp, [DIR_NORTH - 1] = MetatileBehavior_IsNorthArrowWarp,
MetatileBehavior_IsWestArrowWarp, [DIR_WEST - 1] = MetatileBehavior_IsWestArrowWarp,
MetatileBehavior_IsEastArrowWarp, [DIR_EAST - 1] = MetatileBehavior_IsEastArrowWarp,
}; };
static const u8 sRivalAvatarGfxIds[][2] = static const u8 sRivalAvatarGfxIds[][2] =
@ -281,10 +281,10 @@ static const u8 sPlayerAvatarGfxToStateFlag[2][5][2] =
static bool8 (*const sArrowWarpMetatileBehaviorChecks2[])(u8) = //Duplicate of sArrowWarpMetatileBehaviorChecks static bool8 (*const sArrowWarpMetatileBehaviorChecks2[])(u8) = //Duplicate of sArrowWarpMetatileBehaviorChecks
{ {
MetatileBehavior_IsSouthArrowWarp, [DIR_SOUTH - 1] = MetatileBehavior_IsSouthArrowWarp,
MetatileBehavior_IsNorthArrowWarp, [DIR_NORTH - 1] = MetatileBehavior_IsNorthArrowWarp,
MetatileBehavior_IsWestArrowWarp, [DIR_WEST - 1] = MetatileBehavior_IsWestArrowWarp,
MetatileBehavior_IsEastArrowWarp, [DIR_EAST - 1] = MetatileBehavior_IsEastArrowWarp,
}; };
static bool8 (*const sPushBoulderFuncs[])(struct Task *, struct ObjectEvent *, struct ObjectEvent *) = static bool8 (*const sPushBoulderFuncs[])(struct Task *, struct ObjectEvent *, struct ObjectEvent *) =
@ -929,9 +929,9 @@ static bool8 PlayerCheckIfAnimFinishedOrInactive(void)
return ObjectEventCheckHeldMovementStatus(&gObjectEvents[gPlayerAvatar.objectEventId]); return ObjectEventCheckHeldMovementStatus(&gObjectEvents[gPlayerAvatar.objectEventId]);
} }
static void PlayerSetCopyableMovement(u8 a) static void PlayerSetCopyableMovement(u8 movement)
{ {
gObjectEvents[gPlayerAvatar.objectEventId].playerCopyableMovement = a; gObjectEvents[gPlayerAvatar.objectEventId].playerCopyableMovement = movement;
} }
u8 PlayerGetCopyableMovement(void) u8 PlayerGetCopyableMovement(void)
@ -955,65 +955,65 @@ void PlayerSetAnimId(u8 movementActionId, u8 copyableMovement)
void PlayerWalkNormal(u8 direction) void PlayerWalkNormal(u8 direction)
{ {
PlayerSetAnimId(GetWalkNormalMovementAction(direction), 2); PlayerSetAnimId(GetWalkNormalMovementAction(direction), COPY_MOVE_WALK);
} }
void PlayerWalkFast(u8 direction) void PlayerWalkFast(u8 direction)
{ {
PlayerSetAnimId(GetWalkFastMovementAction(direction), 2); PlayerSetAnimId(GetWalkFastMovementAction(direction), COPY_MOVE_WALK);
} }
void PlayerRideWaterCurrent(u8 a) void PlayerRideWaterCurrent(u8 direction)
{ {
PlayerSetAnimId(GetRideWaterCurrentMovementAction(a), 2); PlayerSetAnimId(GetRideWaterCurrentMovementAction(direction), COPY_MOVE_WALK);
} }
void PlayerWalkFaster(u8 direction) void PlayerWalkFaster(u8 direction)
{ {
PlayerSetAnimId(GetWalkFasterMovementAction(direction), 2); PlayerSetAnimId(GetWalkFasterMovementAction(direction), COPY_MOVE_WALK);
} }
static void PlayerRun(u8 a) static void PlayerRun(u8 direction)
{ {
PlayerSetAnimId(GetPlayerRunMovementAction(a), 2); PlayerSetAnimId(GetPlayerRunMovementAction(direction), COPY_MOVE_WALK);
} }
void PlayerOnBikeCollide(u8 a) void PlayerOnBikeCollide(u8 direction)
{ {
PlayCollisionSoundIfNotFacingWarp(a); PlayCollisionSoundIfNotFacingWarp(direction);
PlayerSetAnimId(GetWalkInPlaceNormalMovementAction(a), 2); PlayerSetAnimId(GetWalkInPlaceNormalMovementAction(direction), COPY_MOVE_WALK);
} }
void PlayerOnBikeCollideWithFarawayIslandMew(u8 a) void PlayerOnBikeCollideWithFarawayIslandMew(u8 direction)
{ {
PlayerSetAnimId(GetWalkInPlaceNormalMovementAction(a), 2); PlayerSetAnimId(GetWalkInPlaceNormalMovementAction(direction), COPY_MOVE_WALK);
} }
static void PlayerNotOnBikeCollide(u8 a) static void PlayerNotOnBikeCollide(u8 direction)
{ {
PlayCollisionSoundIfNotFacingWarp(a); PlayCollisionSoundIfNotFacingWarp(direction);
PlayerSetAnimId(GetWalkInPlaceSlowMovementAction(a), 2); PlayerSetAnimId(GetWalkInPlaceSlowMovementAction(direction), COPY_MOVE_WALK);
} }
static void PlayerNotOnBikeCollideWithFarawayIslandMew(u8 a) static void PlayerNotOnBikeCollideWithFarawayIslandMew(u8 direction)
{ {
PlayerSetAnimId(GetWalkInPlaceSlowMovementAction(a), 2); PlayerSetAnimId(GetWalkInPlaceSlowMovementAction(direction), COPY_MOVE_WALK);
} }
void PlayerFaceDirection(u8 direction) void PlayerFaceDirection(u8 direction)
{ {
PlayerSetAnimId(GetFaceDirectionMovementAction(direction), 1); PlayerSetAnimId(GetFaceDirectionMovementAction(direction), COPY_MOVE_FACE);
} }
void PlayerTurnInPlace(u8 direction) void PlayerTurnInPlace(u8 direction)
{ {
PlayerSetAnimId(GetWalkInPlaceFastMovementAction(direction), 1); PlayerSetAnimId(GetWalkInPlaceFastMovementAction(direction), COPY_MOVE_FACE);
} }
void PlayerJumpLedge(u8 direction) void PlayerJumpLedge(u8 direction)
{ {
PlaySE(SE_LEDGE); PlaySE(SE_LEDGE);
PlayerSetAnimId(GetJump2MovementAction(direction), 8); PlayerSetAnimId(GetJump2MovementAction(direction), COPY_MOVE_JUMP2);
} }
// Stop player on current facing direction once they're done moving and if they're not currently Acro Biking on bumpy slope // Stop player on current facing direction once they're done moving and if they're not currently Acro Biking on bumpy slope
@ -1029,81 +1029,82 @@ void PlayerFreeze(void)
// wheelie idle // wheelie idle
void PlayerIdleWheelie(u8 direction) void PlayerIdleWheelie(u8 direction)
{ {
PlayerSetAnimId(GetAcroWheelieFaceDirectionMovementAction(direction), 1); PlayerSetAnimId(GetAcroWheelieFaceDirectionMovementAction(direction), COPY_MOVE_FACE);
} }
// normal to wheelie // normal to wheelie
void PlayerStartWheelie(u8 direction) void PlayerStartWheelie(u8 direction)
{ {
PlayerSetAnimId(GetAcroPopWheelieFaceDirectionMovementAction(direction), 1); PlayerSetAnimId(GetAcroPopWheelieFaceDirectionMovementAction(direction), COPY_MOVE_FACE);
} }
// wheelie to normal // wheelie to normal
void PlayerEndWheelie(u8 direction) void PlayerEndWheelie(u8 direction)
{ {
PlayerSetAnimId(GetAcroEndWheelieFaceDirectionMovementAction(direction), 1); PlayerSetAnimId(GetAcroEndWheelieFaceDirectionMovementAction(direction), COPY_MOVE_FACE);
} }
// wheelie hopping standing // wheelie hopping standing
void PlayerStandingHoppingWheelie(u8 a) void PlayerStandingHoppingWheelie(u8 direction)
{ {
PlaySE(SE_BIKE_HOP); PlaySE(SE_BIKE_HOP);
PlayerSetAnimId(GetAcroWheelieHopFaceDirectionMovementAction(a), 1); PlayerSetAnimId(GetAcroWheelieHopFaceDirectionMovementAction(direction), COPY_MOVE_FACE);
} }
// wheelie hopping moving // wheelie hopping moving
void PlayerMovingHoppingWheelie(u8 a) void PlayerMovingHoppingWheelie(u8 direction)
{ {
PlaySE(SE_BIKE_HOP); PlaySE(SE_BIKE_HOP);
PlayerSetAnimId(GetAcroWheelieHopDirectionMovementAction(a), 2); PlayerSetAnimId(GetAcroWheelieHopDirectionMovementAction(direction), COPY_MOVE_WALK);
} }
// wheelie hopping ledge // wheelie hopping ledge
void PlayerLedgeHoppingWheelie(u8 a) void PlayerLedgeHoppingWheelie(u8 direction)
{ {
PlaySE(SE_BIKE_HOP); PlaySE(SE_BIKE_HOP);
PlayerSetAnimId(GetAcroWheelieJumpDirectionMovementAction(a), 8); PlayerSetAnimId(GetAcroWheelieJumpDirectionMovementAction(direction), COPY_MOVE_JUMP2);
} }
// acro turn jump // acro turn jump
void PlayerAcroTurnJump(u8 direction) void PlayerAcroTurnJump(u8 direction)
{ {
PlaySE(SE_BIKE_HOP); PlaySE(SE_BIKE_HOP);
PlayerSetAnimId(GetJumpInPlaceTurnAroundMovementAction(direction), 1); PlayerSetAnimId(GetJumpInPlaceTurnAroundMovementAction(direction), COPY_MOVE_FACE);
} }
void PlayerWheelieInPlace(u8 direction) void PlayerWheelieInPlace(u8 direction)
{ {
PlaySE(SE_WALL_HIT); PlaySE(SE_WALL_HIT);
PlayerSetAnimId(GetAcroWheelieInPlaceDirectionMovementAction(direction), 2); PlayerSetAnimId(GetAcroWheelieInPlaceDirectionMovementAction(direction), COPY_MOVE_WALK);
} }
void PlayerPopWheelieWhileMoving(u8 direction) void PlayerPopWheelieWhileMoving(u8 direction)
{ {
PlayerSetAnimId(GetAcroPopWheelieMoveDirectionMovementAction(direction), 2); PlayerSetAnimId(GetAcroPopWheelieMoveDirectionMovementAction(direction), COPY_MOVE_WALK);
} }
void PlayerWheelieMove(u8 direction) void PlayerWheelieMove(u8 direction)
{ {
PlayerSetAnimId(GetAcroWheelieMoveDirectionMovementAction(direction), 2); PlayerSetAnimId(GetAcroWheelieMoveDirectionMovementAction(direction), COPY_MOVE_WALK);
} }
void PlayerEndWheelieWhileMoving(u8 direction) void PlayerEndWheelieWhileMoving(u8 direction)
{ {
PlayerSetAnimId(GetAcroEndWheelieMoveDirectionMovementAction(direction), 2); PlayerSetAnimId(GetAcroEndWheelieMoveDirectionMovementAction(direction), COPY_MOVE_WALK);
} }
static void PlayCollisionSoundIfNotFacingWarp(u8 a) static void PlayCollisionSoundIfNotFacingWarp(u8 direction)
{ {
s16 x, y; s16 x, y;
u8 metatileBehavior = gObjectEvents[gPlayerAvatar.objectEventId].currentMetatileBehavior; u8 metatileBehavior = gObjectEvents[gPlayerAvatar.objectEventId].currentMetatileBehavior;
if (!sArrowWarpMetatileBehaviorChecks[a - 1](metatileBehavior)) if (!sArrowWarpMetatileBehaviorChecks[direction - 1](metatileBehavior))
{ {
if (a == 2) // Check if walking up into a door
if (direction == DIR_NORTH)
{ {
PlayerGetDestCoords(&x, &y); PlayerGetDestCoords(&x, &y);
MoveCoords(2, &x, &y); MoveCoords(direction, &x, &y);
if (MetatileBehavior_IsWarpDoor(MapGridGetMetatileBehaviorAt(x, y))) if (MetatileBehavior_IsWarpDoor(MapGridGetMetatileBehaviorAt(x, y)))
return; return;
} }

View File

@ -719,7 +719,7 @@ void ApplyWeatherGammaShiftIfIdle(s8 gammaIndex)
} }
} }
void sub_80ABC7C(u8 gammaIndex, u8 gammaTargetIndex, u8 gammaStepDelay) void ApplyWeatherGammaShiftIfIdle_Gradual(u8 gammaIndex, u8 gammaTargetIndex, u8 gammaStepDelay)
{ {
if (gWeatherPtr->palProcessingState == WEATHER_PAL_STATE_IDLE) if (gWeatherPtr->palProcessingState == WEATHER_PAL_STATE_IDLE)
{ {
@ -779,7 +779,7 @@ void FadeScreen(u8 mode, s8 delay)
if (fadeOut) if (fadeOut)
{ {
if (useWeatherPal) if (useWeatherPal)
CpuFastCopy(gPlttBufferFaded, gPlttBufferUnfaded, 0x400); CpuFastCopy(gPlttBufferFaded, gPlttBufferUnfaded, PLTT_BUFFER_SIZE * 2);
BeginNormalPaletteFade(PALETTES_ALL, delay, 0, 16, fadeColor); BeginNormalPaletteFade(PALETTES_ALL, delay, 0, 16, fadeColor);
gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_SCREEN_FADING_OUT; gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_SCREEN_FADING_OUT;

View File

@ -1181,7 +1181,7 @@ void Thunderstorm_Main(void)
case TSTORM_STATE_FADE_THUNDER_LONG: case TSTORM_STATE_FADE_THUNDER_LONG:
if (--gWeatherPtr->thunderDelay == 0) if (--gWeatherPtr->thunderDelay == 0)
{ {
sub_80ABC7C(19, 3, 5); ApplyWeatherGammaShiftIfIdle_Gradual(19, 3, 5);
gWeatherPtr->initStep++; gWeatherPtr->initStep++;
} }
break; break;

View File

@ -214,10 +214,11 @@ int GetNicknameLanguage(u8 *str)
return GAME_LANGUAGE; return GAME_LANGUAGE;
} }
void sub_81DB620(int windowId, int columnStart, int rowStart, int numFillTiles, int numRows) // Used by Pokénav's Match Call to erase the previous trainer's flavor text when switching between their info pages.
void FillWindowTilesByRow(int windowId, int columnStart, int rowStart, int numFillTiles, int numRows)
{ {
u8 *windowTileData; u8 *windowTileData;
int fillSize, windowRowSize, rowsToFill; int fillSize, windowRowSize, i;
struct Window *window = &gWindows[windowId]; struct Window *window = &gWindows[windowId];
fillSize = numFillTiles * TILE_SIZE_4BPP; fillSize = numFillTiles * TILE_SIZE_4BPP;
@ -225,12 +226,10 @@ void sub_81DB620(int windowId, int columnStart, int rowStart, int numFillTiles,
windowTileData = window->tileData + (rowStart * windowRowSize) + (columnStart * TILE_SIZE_4BPP); windowTileData = window->tileData + (rowStart * windowRowSize) + (columnStart * TILE_SIZE_4BPP);
if (numRows > 0) if (numRows > 0)
{ {
rowsToFill = numRows; for (i = numRows; i != 0; i--)
while (rowsToFill)
{ {
CpuFastFill8(0x11, windowTileData, fillSize); CpuFastFill8(0x11, windowTileData, fillSize);
windowTileData += windowRowSize; windowTileData += windowRowSize;
rowsToFill--;
} }
} }
} }

View File

@ -669,7 +669,7 @@ void VBlankCB_BagMenuRun(void)
static void CB2_Bag(void) static void CB2_Bag(void)
{ {
while(MenuHelpers_CallLinkSomething() != TRUE && SetupBagMenu() != TRUE && MenuHelpers_LinkSomething() != TRUE) while(MenuHelpers_ShouldWaitForLinkRecv() != TRUE && SetupBagMenu() != TRUE && MenuHelpers_IsLinkActive() != TRUE)
{}; {};
} }
@ -705,7 +705,7 @@ static bool8 SetupBagMenu(void)
gMain.state++; gMain.state++;
break; break;
case 6: case 6:
if (!MenuHelpers_LinkSomething()) if (!MenuHelpers_IsLinkActive())
ResetTasks(); ResetTasks();
gMain.state++; gMain.state++;
break; break;
@ -1215,7 +1215,7 @@ static void Task_BagMenu_HandleInput(u8 taskId)
u16* cursorPos = &gBagPosition.cursorPosition[gBagPosition.pocket]; u16* cursorPos = &gBagPosition.cursorPosition[gBagPosition.pocket];
s32 listPosition; s32 listPosition;
if (MenuHelpers_CallLinkSomething() != TRUE && !gPaletteFade.active) if (MenuHelpers_ShouldWaitForLinkRecv() != TRUE && !gPaletteFade.active)
{ {
switch (GetSwitchBagPocketDirection()) switch (GetSwitchBagPocketDirection())
{ {
@ -1354,7 +1354,7 @@ static void Task_SwitchBagPocket(u8 taskId)
{ {
s16* data = gTasks[taskId].data; s16* data = gTasks[taskId].data;
if (!MenuHelpers_LinkSomething() && !IsWallysBag()) if (!MenuHelpers_IsLinkActive() && !IsWallysBag())
{ {
switch (GetSwitchBagPocketDirection()) switch (GetSwitchBagPocketDirection())
{ {
@ -1449,7 +1449,7 @@ static void Task_HandleSwappingItemsInput(u8 taskId)
{ {
s16* data = gTasks[taskId].data; s16* data = gTasks[taskId].data;
if (MenuHelpers_CallLinkSomething() != TRUE) if (MenuHelpers_ShouldWaitForLinkRecv() != TRUE)
{ {
if (JOY_NEW(SELECT_BUTTON)) if (JOY_NEW(SELECT_BUTTON))
{ {
@ -1589,7 +1589,7 @@ static void OpenContextMenu(u8 taskId)
case ITEMMENULOCATION_BERRY_TREE: case ITEMMENULOCATION_BERRY_TREE:
case ITEMMENULOCATION_ITEMPC: case ITEMMENULOCATION_ITEMPC:
default: default:
if (MenuHelpers_LinkSomething() == TRUE || InUnionRoom() == TRUE) if (MenuHelpers_IsLinkActive() == TRUE || InUnionRoom() == TRUE)
{ {
if (gBagPosition.pocket == KEYITEMS_POCKET || !IsHoldingItemAllowed(gSpecialVar_ItemId)) if (gBagPosition.pocket == KEYITEMS_POCKET || !IsHoldingItemAllowed(gSpecialVar_ItemId))
{ {
@ -1691,7 +1691,7 @@ static void Task_ItemContext_Normal(u8 taskId)
static void Task_ItemContext_SingleRow(u8 taskId) static void Task_ItemContext_SingleRow(u8 taskId)
{ {
if (MenuHelpers_CallLinkSomething() != TRUE) if (MenuHelpers_ShouldWaitForLinkRecv() != TRUE)
{ {
s8 selection = Menu_ProcessInputNoWrap(); s8 selection = Menu_ProcessInputNoWrap();
switch (selection) switch (selection)
@ -1712,7 +1712,7 @@ static void Task_ItemContext_SingleRow(u8 taskId)
static void Task_ItemContext_MultipleRows(u8 taskId) static void Task_ItemContext_MultipleRows(u8 taskId)
{ {
if (MenuHelpers_CallLinkSomething() != TRUE) if (MenuHelpers_ShouldWaitForLinkRecv() != TRUE)
{ {
s8 cursorPos = Menu_GetCursorPos(); s8 cursorPos = Menu_GetCursorPos();
if (JOY_NEW(DPAD_UP)) if (JOY_NEW(DPAD_UP))

View File

@ -612,7 +612,7 @@ static void Task_StandingOnHiddenItem(u8 taskId)
void ItemUseOutOfBattle_PokeblockCase(u8 taskId) void ItemUseOutOfBattle_PokeblockCase(u8 taskId)
{ {
if (MenuHelpers_LinkSomething() == TRUE) // link func if (MenuHelpers_IsLinkActive() == TRUE)
{ {
DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].tUsingRegisteredKeyItem); DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].tUsingRegisteredKeyItem);
} }

View File

@ -4,11 +4,36 @@
.include "asm/macros.inc" .include "asm/macros.inc"
.include "constants/constants.inc" .include "constants/constants.inc"
.equiv GCMB_STRUCT_COUNTER1, 0x00
.equiv GCMB_STRUCT_COUNTER2, 0x01
.equiv GCMB_STRUCT_MBPROGRESS, 0x02
.equiv GCMB_STRUCT_SAVEDVCOUNT, 0x03
.equiv GCMB_STRUCT_KEYA, 0x04
.equiv GCMB_STRUCT_KEYB, 0x08
.equiv GCMB_STRUCT_KEYC, 0x0C
.equiv GCMB_STRUCT_BOOT_KEY, 0x10
.equiv GCMB_STRUCT_IMAGE_SIZE, 0x12
.equiv GCMB_STRUCT_SESSION_KEY, 0x14
.equiv GCMB_STRUCT_HASH_VAL, 0x18
.equiv GCMB_STRUCT_KEYC_DERIVATION, 0x1C
.equiv GCMB_STRUCT_BASE_DEST_PTR, 0x20 .equiv GCMB_STRUCT_BASE_DEST_PTR, 0x20
.equiv GCMB_STRUCT_CUR_DEST_PTR, 0x24 .equiv GCMB_STRUCT_CUR_DEST_PTR, 0x24
.equiv GCMB_STRUCT_SERIAL_INTR_HANDLER, 0x28 .equiv GCMB_STRUCT_SERIAL_INTR_HANDLER, 0x28
.equiv ROM_HEADER_NINTENDO_LOGO_OFFSET, 0x4 .equiv ROM_HEADER_NINTENDO_LOGO_OFFSET, 0x04
.equiv ROM_HEADER_NINTENDO_LOGO_LENGTH, 0x98
.equiv ROM_HEADER_NINTENDO_LOGO_END, 0xA0
.equiv MBPROGRESS_NONE, 0x00
.equiv MBPROGRESS_LOGO_CORRECT, 0x01
.equiv MBPROGRESS_READY_TO_BOOT, 0x02
.equiv GCMB_MAGIC_BOOTKEY_HASHVAL, 0xBB
.equiv GCMB_MAGIC_BOOTKEY, 0xBB
.equiv GCMB_MAGIC_COUNTER2, 0xCC
.equiv GCMB_MAGIC_KEYA, 0xDD
.equiv GCMB_MAGIC_KEYB, 0xEE
.equiv GCMB_MAGIC_KEYCDERIVATION, 0xFF
.syntax unified .syntax unified
@ -22,7 +47,7 @@ GameCubeMultiBoot_Hash: @ 82DED70
movs r2, 0x20 movs r2, 0x20
GameCubeMultiBoot_Hash_Loop: GameCubeMultiBoot_Hash_Loop:
lsrs r3, #1 lsrs r3, 1
bcc GameCubeMultiBoot_Hash_SkipEor bcc GameCubeMultiBoot_Hash_SkipEor
eors r3, r4 eors r3, r4
@ -37,137 +62,177 @@ GameCubeMultiBoot_Hash_SkipEor:
thumb_func_start GameCubeMultiBoot_Main thumb_func_start GameCubeMultiBoot_Main
@ void GameCubeMultiBoot_Main(struct GameCubeMultiBoot *mb); @ void GameCubeMultiBoot_Main(struct GameCubeMultiBoot *mb);
GameCubeMultiBoot_Main: @ 82DED84 GameCubeMultiBoot_Main: @ 82DED84
ldr r1, [r0, #GCMB_STRUCT_SERIAL_INTR_HANDLER] @ If there is no interrupt handler, skip counter manipulation
cmp r1, #0 ldr r1, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER]
beq _082DEDAA
ldrb r1, [r0, 0x1]
adds r1, 0x1
strb r1, [r0, 0x1]
ldrb r1, [r0, 0x2]
cmp r1, 0x2
beq _082DEDF4
ldr r3, pool_InterruptRegs
ldrh r2, [r3, #OFFSET_REG_IME - 0x200]
movs r1, 0
strh r1, [r3, #OFFSET_REG_IME - 0x200]
ldrb r1, [r0]
cmp r1, 0xA
bgt _082DEDA8
adds r1, 0x1
strb r1, [r0]
_082DEDA8:
strh r2, [r3, #OFFSET_REG_IME - 0x200]
_082DEDAA:
bcs GameCubeMultiBoot_Init
ldrb r1, [r0, 0x2]
cmp r1, 0 cmp r1, 0
bne _082DEDF6 beq GameCubeMultiBoot_Main_SkipCounters
ldr r1, [r0, #GCMB_STRUCT_CUR_DEST_PTR] @ Increment the second counter
ldr r2, [r0, #GCMB_STRUCT_BASE_DEST_PTR] ldrb r1, [r0, GCMB_STRUCT_COUNTER2]
adds r1, 0x1
strb r1, [r0, GCMB_STRUCT_COUNTER2]
@ If there is nothing more to do, bail out
ldrb r1, [r0, GCMB_STRUCT_MBPROGRESS]
cmp r1, MBPROGRESS_READY_TO_BOOT
beq GameCubeMultiBoot_Main_Return
@ Save current interrupt master register value
ldr r3, pool_InterruptRegs
ldrh r2, [r3, OFFSET_REG_IME - 0x200]
@ Disable all interrupts
movs r1, 0
strh r1, [r3, OFFSET_REG_IME - 0x200]
@ Increment the first counter, if it's less than or equal to 10.
ldrb r1, [r0, GCMB_STRUCT_COUNTER1]
cmp r1, 0xA
bgt GameCubeMultiBoot_Main_SkipCounter1Inc
adds r1, 0x1
strb r1, [r0, GCMB_STRUCT_COUNTER1]
GameCubeMultiBoot_Main_SkipCounter1Inc:
@ Load the saved interrupt master register value (re-enables interrupts if they were enabled before)
strh r2, [r3, OFFSET_REG_IME - 0x200]
GameCubeMultiBoot_Main_SkipCounters:
@ Initialise multiboot structures if required
bcs GameCubeMultiBoot_Init
@ Skip this section (check Nintendo logo) if the check has already passed
ldrb r1, [r0, GCMB_STRUCT_MBPROGRESS]
cmp r1, MBPROGRESS_NONE
bne GameCubeMultiBoot_Main_SkipLogoCheck
@ Bail out if no multiboot image data has been transferred yet
ldr r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
ldr r2, [r0, GCMB_STRUCT_BASE_DEST_PTR]
subs r1, r2 subs r1, r2
beq _082DEE76 beq GameCubeMultiBoot_Main_Return2
cmp r1, 0xA0 @ Also bail out if not enough data has been transferred
bcc _082DEE76 cmp r1, ROM_HEADER_NINTENDO_LOGO_END
bcc GameCubeMultiBoot_Main_Return2
@ Compare the Nintendo logo of the transferred multiboot image header, with the one in the ROM image of the inserted cart
push {r4-r6} push {r4-r6}
movs r1, 0x98 movs r1, ROM_HEADER_NINTENDO_LOGO_LENGTH
adds r2, #ROM_HEADER_NINTENDO_LOGO_OFFSET adds r2, ROM_HEADER_NINTENDO_LOGO_OFFSET
ldr r4, pool_NintendoLogo ldr r4, pool_NintendoLogo
_082DEDC6: GameCubeMultiBoot_Main_LogoCmpLoop:
ldm r2!, {r5} ldm r2!, {r5}
ldm r4!, {r6} ldm r4!, {r6}
cmp r5, r6 cmp r5, r6
bne _082DEDDC bne GameCubeMultiBoot_Main_LogoCmpEnd
subs r1, 0x4 subs r1, 0x4
bne _082DEDC6 bne GameCubeMultiBoot_Main_LogoCmpLoop
ldm r2!, {r5} ldm r2!, {r5}
ldm r4!, {r6} ldm r4!, {r6}
eors r5, r6 eors r5, r6
lsrs r5, #8 lsrs r5, 8
str r2, [r0, #GCMB_STRUCT_BASE_DEST_PTR] str r2, [r0, GCMB_STRUCT_BASE_DEST_PTR]
_082DEDDC: GameCubeMultiBoot_Main_LogoCmpEnd:
pop {r4-r6} pop {r4-r6}
@ Throw everything away if the logo data didn't match
bne GameCubeMultiBoot_Init bne GameCubeMultiBoot_Init
movs r1, 0x1 @ Logo matched, set the relevent multiboot progress bit
strb r1, [r0, 0x2] movs r1, MBPROGRESS_LOGO_CORRECT
ldr r1, [r0, 0x4] strb r1, [r0, GCMB_STRUCT_MBPROGRESS]
ldr r2, [r0, 0x8] @ XOR together KeyA and KeyB to get the initial multiboot image checksum value
ldr r1, [r0, GCMB_STRUCT_KEYA]
ldr r2, [r0, GCMB_STRUCT_KEYB]
eors r1, r2 eors r1, r2
str r1, [r0, 0x18] str r1, [r0, GCMB_STRUCT_HASH_VAL]
@ ...also use it as the initial value for the image encryption session key. Algorithm is the same as the GBA BIOS multiboot: sessionkey = (initialvalue * 0x6177614b) + 1
ldr r2, pool_Kawa ldr r2, pool_Kawa
muls r1, r2 muls r1, r2
adds r1, 0x1 adds r1, 0x1
str r1, [r0, 0x14] str r1, [r0, GCMB_STRUCT_SESSION_KEY]
_082DEDF4: GameCubeMultiBoot_Main_Return:
bx lr bx lr
_082DEDF6: GameCubeMultiBoot_Main_SkipLogoCheck:
ldr r1, [r0, #GCMB_STRUCT_CUR_DEST_PTR] @ If this code is executed, then the logo check has passed, and the data being transferred in is encrypted.
@ Set up registers.
ldr r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
mov r12, r1 mov r12, r1
ldr r3, [r0, 0x18] ldr r3, [r0, GCMB_STRUCT_HASH_VAL]
push {r4-r7} push {r4-r7}
ldr r4, [r0, #GCMB_STRUCT_BASE_DEST_PTR] ldr r4, [r0, GCMB_STRUCT_BASE_DEST_PTR]
ldr r5, pool_Kawa ldr r5, pool_Kawa
ldr r6, [r0, 0x14] ldr r6, [r0, GCMB_STRUCT_SESSION_KEY]
ldr r7, pool_HashVal ldr r7, pool_HashVal
_082DEE06: GameCubeMultiBoot_Main_ImageDecryptHashLoop:
@ If there's no more data, break out of the loop
cmp r4, r12 cmp r4, r12
bcs _082DEE26 bcs GameCubeMultiBoot_Main_ImageDecryptHashEnd
@ Get the next uint32
ldr r1, [r4] ldr r1, [r4]
@ Decrypt the ciphertext: plaintext = (ciphertext ^ sessionkey) + hashval
eors r1, r6 eors r1, r6
adds r1, r3 adds r1, r3
@ Save the current uint32 of plaintext and advance the pointer
stm r4!, {r1} stm r4!, {r1}
@ Advance the hashval with this uint32 of plaintext -- this is the same code as GameCubeMultiBoot_Hash.
eors r3, r1 eors r3, r1
movs r2, 0x20 movs r2, 0x20
_082DEE16: GameCubeMultiBoot_Main_HashLoop:
lsrs r3, #1 lsrs r3, 1
bcc _082DEE1C bcc GameCubeMultiBoot_Main_HashSkipEor
eors r3, r7 eors r3, r7
_082DEE1C: GameCubeMultiBoot_Main_HashSkipEor:
subs r2, 0x1 subs r2, 0x1
bne _082DEE16 bne GameCubeMultiBoot_Main_HashLoop
@ Advance the sessionkey with the usual algorithm: sessionkey = (sessionkey * 0x6177614b) + 1
muls r6, r5 muls r6, r5
adds r6, 0x1 adds r6, 0x1
b _082DEE06 b GameCubeMultiBoot_Main_ImageDecryptHashLoop
_082DEE26: GameCubeMultiBoot_Main_ImageDecryptHashEnd:
str r4, [r0, #GCMB_STRUCT_BASE_DEST_PTR] @ Save the new pointer, sessionkey, hashval
str r6, [r0, 0x14] str r4, [r0, GCMB_STRUCT_BASE_DEST_PTR]
str r6, [r0, GCMB_STRUCT_SESSION_KEY]
pop {r4-r7} pop {r4-r7}
str r3, [r0, 0x18] str r3, [r0, GCMB_STRUCT_HASH_VAL]
ldrh r1, [r0, 0x12] @ Bail out if the image size is unknown
cmp r1, #0 ldrh r1, [r0, GCMB_STRUCT_IMAGE_SIZE]
bne _082DEE76 cmp r1, 0
ldr r1, [r0, #GCMB_STRUCT_CUR_DEST_PTR] bne GameCubeMultiBoot_Main_Return2
ldr r2, [r0, #GCMB_STRUCT_BASE_DEST_PTR] @ Bail out if no image data has been transferred
ldr r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
ldr r2, [r0, GCMB_STRUCT_BASE_DEST_PTR]
cmp r1, r2 cmp r1, r2
bne _082DEE76 bne GameCubeMultiBoot_Main_Return2
ldr r1, [r0, 0xC] @ If KeyC hasn't been generated yet, go generate it
cmp r1, #0 ldr r1, [r0, GCMB_STRUCT_KEYC]
beq _082DEE60 cmp r1, 0
ldrh r1, [r0, 0x10] beq GameCubeMultiBoot_Main_GenerateKeyC
cmp r1, #0 @ If the other side hasn't sent its boot key yet, bail out
beq _082DEDF4 ldrh r1, [r0, GCMB_STRUCT_BOOT_KEY]
cmp r1, 0
beq GameCubeMultiBoot_Main_Return
@ Save off LR so it doesn't get clobbered by the upcoming function call
mov r12, lr mov r12, lr
movs r1, 0xBB @ Generate the real boot key, which is the checksum of a hardcoded value and KeyC
ldr r3, [r0, 0xC] movs r1, GCMB_MAGIC_BOOTKEY_HASHVAL
ldr r3, [r0, GCMB_STRUCT_KEYC]
bl GameCubeMultiBoot_Hash bl GameCubeMultiBoot_Hash
ldrh r1, [r0, 0x10] ldrh r1, [r0, GCMB_STRUCT_BOOT_KEY]
@ Restore the saved LR value
mov lr, r12 mov lr, r12
@ Compare the two boot keys (real and passed in), if they don't match then throw everything away
subs r1, r3 subs r1, r3
bne GameCubeMultiBoot_Init bne GameCubeMultiBoot_Init
movs r1, 0x2 @ The two boot keys matched, tell the caller that the image is ready to boot
strb r1, [r0, 0x2] movs r1, MBPROGRESS_READY_TO_BOOT
strb r1, [r0, GCMB_STRUCT_MBPROGRESS]
@ Nothing more to do, return.
bx lr bx lr
_082DEE60: GameCubeMultiBoot_Main_GenerateKeyC:
@ Save off LR so it doesn't get clobbered by the upcoming function call
mov r12, lr mov r12, lr
ldrb r1, [r0, 0x3] @ KeyC = (SavedVCount << 24) - 1
lsls r1, #24 ldrb r1, [r0, GCMB_STRUCT_SAVEDVCOUNT]
lsls r1, 24
subs r1, 0x1 subs r1, 0x1
str r1, [r0, 0xC] str r1, [r0, GCMB_STRUCT_KEYC]
@ Hash the KeyC with the multiboot image checksum to generate the KeyC derivation material to be sent to the other side of the link
bl GameCubeMultiBoot_Hash bl GameCubeMultiBoot_Hash
lsls r3, #8 @ Make sure the sent KeyC derivation material contains a magic value so that the other side can detect it
adds r3, 0xFF lsls r3, 8
str r3, [r0, 0x1C] adds r3, GCMB_MAGIC_KEYCDERIVATION
@ Save off the KeyC derivation material and return to caller
str r3, [r0, GCMB_STRUCT_KEYC_DERIVATION]
bx r12 bx r12
_082DEE76: GameCubeMultiBoot_Main_Return2:
bx lr bx lr
thumb_func_end GameCubeMultiBoot_Main thumb_func_end GameCubeMultiBoot_Main
@ -182,12 +247,15 @@ pool_NintendoLogo: .4byte RomHeaderNintendoLogo
thumb_func_start GameCubeMultiBoot_ExecuteProgram thumb_func_start GameCubeMultiBoot_ExecuteProgram
@ void GameCubeMultiBoot_ExecuteProgram(struct GameCubeMultiBoot *mb); @ void GameCubeMultiBoot_ExecuteProgram(struct GameCubeMultiBoot *mb);
GameCubeMultiBoot_ExecuteProgram: @ 82DEE84 GameCubeMultiBoot_ExecuteProgram: @ 82DEE84
ldrb r1, [r0, 0x2] @ If there's no multiboot image ready, just return to caller
cmp r1, 0x2 ldrb r1, [r0, GCMB_STRUCT_MBPROGRESS]
cmp r1, MBPROGRESS_READY_TO_BOOT
bne GameCubeMultiBoot_ExecuteProgram_Fail bne GameCubeMultiBoot_ExecuteProgram_Fail
@ Disable interrupts
ldr r3, pool_InterruptRegs ldr r3, pool_InterruptRegs
movs r1, #0 movs r1, 0
strh r1, [r3, #OFFSET_REG_IME - 0x200] strh r1, [r3, OFFSET_REG_IME - 0x200]
@ Jump to the real entry point of the multiboot image (past the image header), in ARM mode
ldr r1, pool_MultiBootLoadAddr ldr r1, pool_MultiBootLoadAddr
adds r1, 0xC0 adds r1, 0xC0
bx r1 bx r1
@ -201,25 +269,25 @@ GameCubeMultiBoot_Init: @ 82DEE98
ldr r3, pool_InterruptRegs ldr r3, pool_InterruptRegs
@ Save IME register. @ Save IME register.
ldrh r2, [r3, #OFFSET_REG_IME - 0x200] ldrh r2, [r3, OFFSET_REG_IME - 0x200]
@ Disable interrupts. @ Disable interrupts.
movs r1, 0 movs r1, 0
strh r1, [r3, #OFFSET_REG_IME - 0x200] strh r1, [r3, OFFSET_REG_IME - 0x200]
@ Set the handler to the "Stop" routine. @ Set the handler to the "Stop" routine.
@ Unless the first command that is received is a device reset command, the @ Unless the first command that is received is a device reset command, the
@ "Stop" routine will be executed and no further commands will be processed. @ "Stop" routine will be executed and no further commands will be processed.
adr r3, GcMbIntrHandler_Stop adr r3, GcMbIntrHandler_Stop
str r3, [r0, #GCMB_STRUCT_SERIAL_INTR_HANDLER] str r3, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER]
ldrb r3, [r0, 0x3] ldrb r3, [r0, 0x3]
push {r3} push {r3}
ldrb r3, [r0, 0x1] ldrb r3, [r0, 0x1]
push {r0,r3} push {r0,r3}
adds r3, r0, #0 adds r3, r0, 0
adds r3, #GCMB_STRUCT_BASE_DEST_PTR adds r3, GCMB_STRUCT_BASE_DEST_PTR
@ clear all but the last 3 fields of the struct @ clear all but the last 3 fields of the struct
GameCubeMultiBoot_Init_ClearStructLoop: GameCubeMultiBoot_Init_ClearStructLoop:
@ -261,7 +329,7 @@ GameCubeMultiBoot_Init_ClearStructLoop:
strh r1, [r3, OFFSET_REG_IE - 0x200] strh r1, [r3, OFFSET_REG_IE - 0x200]
@ Restore IME register. @ Restore IME register.
strh r2, [r3, #OFFSET_REG_IME - 0x200] strh r2, [r3, OFFSET_REG_IME - 0x200]
bx lr bx lr
thumb_func_end GameCubeMultiBoot_Init thumb_func_end GameCubeMultiBoot_Init
@ -275,11 +343,11 @@ GameCubeMultiBoot_HandleSerialInterrupt: @ 82DEEE2
ldrh r1, [r3, OFFSET_REG_JOYCNT - 0x120] ldrh r1, [r3, OFFSET_REG_JOYCNT - 0x120]
strh r1, [r3, OFFSET_REG_JOYCNT - 0x120] strh r1, [r3, OFFSET_REG_JOYCNT - 0x120]
movs r2, #0 movs r2, 0
strb r2, [r0] strb r2, [r0]
ldr r2, [r0, #GCMB_STRUCT_SERIAL_INTR_HANDLER] ldr r2, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER]
cmp r2, #0 cmp r2, 0
beq GameCubeMultiBoot_HandleSerialInterruptDone beq GameCubeMultiBoot_HandleSerialInterruptDone
lsrs r1, 1 @ was a device reset command received? lsrs r1, 1 @ was a device reset command received?
@ -297,7 +365,7 @@ GcMbIntrHandler_Stop:
strh r2, [r3, OFFSET_REG_JOYSTAT - 0x120] strh r2, [r3, OFFSET_REG_JOYSTAT - 0x120]
GameCubeMultiBoot_SetInterruptHandler: GameCubeMultiBoot_SetInterruptHandler:
str r2, [r0, #GCMB_STRUCT_SERIAL_INTR_HANDLER] str r2, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER]
GameCubeMultiBoot_ReadVCount: GameCubeMultiBoot_ReadVCount:
ldr r3, pool_RegDispstat ldr r3, pool_RegDispstat
@ -308,19 +376,25 @@ GameCubeMultiBoot_HandleSerialInterruptDone:
bx lr bx lr
GameCubeMultiBoot_BeginHandshake: GameCubeMultiBoot_BeginHandshake:
@ Throw away anything that got sent
ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120] ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
@ Send the game code, the other side of the link must send back the same game code
ldr r1, pool_RubyUSAGameCode ldr r1, pool_RubyUSAGameCode
str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120] str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120]
movs r1, 0x10 movs r1, 0x10
strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120] strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120]
ldrb r1, [r0, 0x3] @ Use the saved VCount value to provide 8 bits of entropy for KeyB
strb r1, [r0, 0x9] ldrb r1, [r0, GCMB_STRUCT_SAVEDVCOUNT]
ldrb r1, [r0, 0x2] strb r1, [r0, GCMB_STRUCT_KEYB + 1]
@ If a multiboot image has been transferred at least enough such that the Nintendo logo check has passed, stop everything.
ldrb r1, [r0, GCMB_STRUCT_MBPROGRESS]
cmp r1, 0 cmp r1, 0
bne GcMbIntrHandler_Stop bne GcMbIntrHandler_Stop
@ Set the image destination pointers.
ldr r1, pool_MultiBootLoadAddr ldr r1, pool_MultiBootLoadAddr
str r1, [r0, #GCMB_STRUCT_BASE_DEST_PTR] str r1, [r0, GCMB_STRUCT_BASE_DEST_PTR]
str r1, [r0, #GCMB_STRUCT_CUR_DEST_PTR] str r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
@ Set the new interrupt handler.
adr r2, GcMbIntrHandler_CheckGameCodeSent adr r2, GcMbIntrHandler_CheckGameCodeSent
b GameCubeMultiBoot_SetInterruptHandler b GameCubeMultiBoot_SetInterruptHandler
@ -347,149 +421,166 @@ GameCubeMultiBoot_CheckHandshakeResponse:
ldr r2, pool_RubyUSAGameCode ldr r2, pool_RubyUSAGameCode
cmp r1, r2 cmp r1, r2
bne GcMbIntrHandler_Stop @ stop if the GameCube didn't reply with the same game code bne GcMbIntrHandler_Stop @ stop if the GameCube didn't reply with the same game code
ldrb r1, [r0, 0x3] @ Use the saved VCount value to provide another 8 bits of entropy for KeyB.
strb r1, [r0, 0xB] ldrb r1, [r0, GCMB_STRUCT_SAVEDVCOUNT]
adr r2, GcMbIntrHandler_82DEF44 strb r1, [r0, GCMB_STRUCT_KEYB + 3]
adr r2, GcMbIntrHandler_ReceiveKeyA
b GameCubeMultiBoot_SetInterruptHandler b GameCubeMultiBoot_SetInterruptHandler
.align 2, 0 .align 2, 0
GcMbIntrHandler_82DEF44: @ 82DEF44 GcMbIntrHandler_ReceiveKeyA: @ 82DEF44
lsrs r1, 1 @ is receive complete? lsrs r1, 1 @ is receive complete?
bcc GcMbIntrHandler_Stop @ branch if not bcc GcMbIntrHandler_Stop @ branch if not
ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120] ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
@ make sure top 8 bits of the received value is the KeyA magic number, stop if KeyA is invalid
lsrs r2, r1, 24 lsrs r2, r1, 24
cmp r2, 0xDD cmp r2, GCMB_MAGIC_KEYA
bne GcMbIntrHandler_Stop bne GcMbIntrHandler_Stop
str r1, [r0, 0x4] @ save received KeyA
ldrb r1, [r0, 0x1] str r1, [r0, GCMB_STRUCT_KEYA]
strb r1, [r0, 0xA] @ use the second GameCubeMultiBoot_Main() counter as another 8 bits of entropy for KeyB
ldrb r1, [r0, GCMB_STRUCT_COUNTER2]
strb r1, [r0, GCMB_STRUCT_KEYB + 2]
movs r2, 0 movs r2, 0
movs r3, 0 movs r3, 0
ldr r1, [r0, 0x8] ldr r1, [r0, GCMB_STRUCT_KEYB]
lsrs r1, 8 lsrs r1, 8
_082DEF5E: @ make sure KeyB is valid (other side of the link is supposed to check KeyB too), if it's not then change the byte that was just set so it is
GameCubeMultiBoot_KeyBCheckLoop:
lsrs r1, 1 lsrs r1, 1
adcs r2, r3 adcs r2, r3
cmp r1, 0 cmp r1, 0
bne _082DEF5E bne GameCubeMultiBoot_KeyBCheckLoop
cmp r2, 0xE cmp r2, 0xE
bgt _082DEF70 bgt GameCubeMultiBoot_KeyBSaveNewByte
cmp r2, 0x7 cmp r2, 0x7
bge _082DEF72 bge GameCubeMultiBoot_KeyBCheckEnd
movs r1, 0xFF movs r1, 0xFF
_082DEF70: GameCubeMultiBoot_KeyBSaveNewByte:
strb r1, [r0, 0xA] strb r1, [r0, GCMB_STRUCT_KEYB + 2]
_082DEF72: GameCubeMultiBoot_KeyBCheckEnd:
ldr r1, [r0, 0x8] @ add in the KeyB magic number and send off KeyB
adds r1, 0xEE ldr r1, [r0, GCMB_STRUCT_KEYB]
adds r1, GCMB_MAGIC_KEYB
ldr r3, pool_SerialRegs ldr r3, pool_SerialRegs
str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120] str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120]
movs r1, 0x30 movs r1, 0x30
strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120] strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120]
adr r2, GcMbIntrHandler_82DEF84 @ set new interrupt handler
adr r2, GcMbIntrHandler_CheckKeyBSent
b GameCubeMultiBoot_SetInterruptHandler b GameCubeMultiBoot_SetInterruptHandler
.align 2, 0 .align 2, 0
GcMbIntrHandler_82DEF84: @ 82DEF84 GcMbIntrHandler_CheckKeyBSent: @ 82DEF84
lsls r1, 31 lsls r1, 31
bcc GcMbIntrHandler_Stop @ stop if send failed bcc GcMbIntrHandler_Stop @ stop if send failed
bmi _082DEF94 @ branch if receive is complete bmi GameCubeMultiBoot_CheckImageSizeResponse @ branch if receive is complete
adr r2, GcMbIntrHandler_82DEF90 adr r2, GcMbIntrHandler_CheckImageSizeResponse
b GameCubeMultiBoot_SetInterruptHandler b GameCubeMultiBoot_SetInterruptHandler
.align 2, 0 .align 2, 0
GcMbIntrHandler_82DEF90: @ 82DEF90 GcMbIntrHandler_CheckImageSizeResponse: @ 82DEF90
lsrs r1, 1 @ is receive complete? lsrs r1, 1 @ is receive complete?
bcc GcMbIntrHandler_Stop @ branch if not bcc GcMbIntrHandler_Stop @ branch if not
_082DEF94: GameCubeMultiBoot_CheckImageSizeResponse:
ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120] ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
ldr r2, _082DF034 ldr r2, GameCubeMultiBoot_MaximumImageSizeUInt32s
cmp r1, r2 cmp r1, r2
bhs GcMbIntrHandler_Stop bhs GcMbIntrHandler_Stop
adds r1, 0x1 adds r1, 0x1
adds r1, r1 adds r1, r1
strh r1, [r0, 0x12] strh r1, [r0, GCMB_STRUCT_IMAGE_SIZE]
ldrb r1, [r0, 0x2] ldrb r1, [r0, GCMB_STRUCT_MBPROGRESS]
cmp r1, 0 cmp r1, 0
_082DEFA6: GcMbIntrHandler_StopIfNotEqual:
bne GcMbIntrHandler_Stop bne GcMbIntrHandler_Stop
ldr r1, pool_MultiBootLoadAddr ldr r1, pool_MultiBootLoadAddr
str r1, [r0, #GCMB_STRUCT_BASE_DEST_PTR] str r1, [r0, GCMB_STRUCT_BASE_DEST_PTR]
str r1, [r0, #GCMB_STRUCT_CUR_DEST_PTR] str r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
adr r2, GcMbIntrHandler_82DEFB4 adr r2, GcMbIntrHandler_CheckImageResponse
b GameCubeMultiBoot_SetInterruptHandler b GameCubeMultiBoot_SetInterruptHandler
.align 2, 0 .align 2, 0
GcMbIntrHandler_82DEFB4: @ 82DEFB4 GcMbIntrHandler_CheckImageResponse: @ 82DEFB4
lsrs r1, 1 @ is receive complete? lsrs r1, 1 @ is receive complete?
bcc GcMbIntrHandler_Stop @ branch if not bcc GcMbIntrHandler_Stop @ branch if not
ldr r2, [r0, #GCMB_STRUCT_CUR_DEST_PTR] ldr r2, [r0, GCMB_STRUCT_CUR_DEST_PTR]
movs r1, 0x4 movs r1, 0x4
ands r1, r2 ands r1, r2
adds r1, 0x8 adds r1, 0x8
lsls r1, 2 lsls r1, 2
strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120] strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120]
@ get the recieved uint32
ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120] ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
@ put it in the current destination pointer and advance that pointer
stm r2!, {r1} stm r2!, {r1}
str r2, [r0, #GCMB_STRUCT_CUR_DEST_PTR] @ save off the advanced pointer
ldrh r1, [r0, 0x12] str r2, [r0, GCMB_STRUCT_CUR_DEST_PTR]
@ decrease the image size (in uint32s)
ldrh r1, [r0, GCMB_STRUCT_IMAGE_SIZE]
subs r1, 0x1 subs r1, 0x1
strh r1, [r0, 0x12] strh r1, [r0, GCMB_STRUCT_IMAGE_SIZE]
@ branch away if the transfer is not yet complete
bne GameCubeMultiBoot_ReadVCount bne GameCubeMultiBoot_ReadVCount
_082DEFD2: GcMbIntrHandler_SendCounter2:
ldrb r1, [r0, 0x1] @ send counter2 with magic number
ldrb r1, [r0, GCMB_STRUCT_COUNTER2]
lsls r1, 8 lsls r1, 8
adds r1, 0xCC adds r1, GCMB_MAGIC_COUNTER2
str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120] str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120]
adr r2, _082DEFE0 adr r2, GcMbIntrHandler_CheckCounter2Sent
b GameCubeMultiBoot_SetInterruptHandler b GameCubeMultiBoot_SetInterruptHandler
.align 2, 0 .align 2, 0
_082DEFE0: GcMbIntrHandler_CheckCounter2Sent:
lsls r1, 31 lsls r1, 31
_082DEFE2: GcMbIntrHandler_StopIfSendFailed:
bcc GcMbIntrHandler_Stop bcc GcMbIntrHandler_Stop @ stop if send failed
ldr r1, [r0, 0x1C] @ if KeyC derivation value has not yet been generated, send Counter2 again, otherwise, send KeyC derivation
ldr r1, [r0, GCMB_STRUCT_KEYC_DERIVATION]
cmp r1, 0 cmp r1, 0
beq _082DEFD2 beq GcMbIntrHandler_SendCounter2
str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120] str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120]
adr r2, GcMbIntrHandler_82DEFF0 adr r2, GcMbIntrHandler_CheckKeyCDerivationSent
b GameCubeMultiBoot_SetInterruptHandler b GameCubeMultiBoot_SetInterruptHandler
.align 2, 0 .align 2, 0
GcMbIntrHandler_82DEFF0: @ 82DEFF0 GcMbIntrHandler_CheckKeyCDerivationSent: @ 82DEFF0
lsls r1, 31 lsls r1, 31
bcc _082DEFE2 @ branch if send failed bcc GcMbIntrHandler_StopIfSendFailed @ branch if send failed
bmi _082DF000 @ branch if receive is complete bmi GameCubeMultiBoot_CheckBootKeyResponse @ branch if receive is complete
adr r2, GcMbIntrHandler_82DEFFC adr r2, GcMbIntrHandler_CheckBootKeyResponse
b GameCubeMultiBoot_SetInterruptHandler b GameCubeMultiBoot_SetInterruptHandler
.align 2, 0 .align 2, 0
GcMbIntrHandler_82DEFFC: @ 82DEFFC GcMbIntrHandler_CheckBootKeyResponse: @ 82DEFFC
lsrs r1, 1 @ is receive complete? lsrs r1, 1 @ is receive complete?
bcc _082DEFE2 @ branch if not bcc GcMbIntrHandler_StopIfSendFailed @ branch if not
_082DF000: GameCubeMultiBoot_CheckBootKeyResponse:
ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120] ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
@ make sure received boot key contains expected magic number, stop if not
lsrs r2, r1, 24 lsrs r2, r1, 24
cmp r2, 0xBB cmp r2, GCMB_MAGIC_BOOTKEY
bne _082DEFA6 bne GcMbIntrHandler_StopIfNotEqual
strh r1, [r0, 0x10] @ save received bootkey to be checked in GameCubeMultiBoot_Main()
adr r2, GcMbIntrHandler_82DF010 strh r1, [r0, GCMB_STRUCT_BOOT_KEY]
@ stop if anything more gets sent
adr r2, GcMbIntrHandler_StopUnconditionally
b GameCubeMultiBoot_SetInterruptHandler b GameCubeMultiBoot_SetInterruptHandler
.align 2, 0 .align 2, 0
GcMbIntrHandler_82DF010: @ 82DF010 GcMbIntrHandler_StopUnconditionally: @ 82DF010
b GcMbIntrHandler_Stop b GcMbIntrHandler_Stop
thumb_func_end GameCubeMultiBoot_HandleSerialInterrupt thumb_func_end GameCubeMultiBoot_HandleSerialInterrupt
@ -500,11 +591,11 @@ GameCubeMultiBoot_Quit: @ 82DF012
ldr r3, pool_InterruptRegs ldr r3, pool_InterruptRegs
@ Save IME register. @ Save IME register.
ldrh r2, [r3, #OFFSET_REG_IME - 0x200] ldrh r2, [r3, OFFSET_REG_IME - 0x200]
@ Disable interrupts. @ Disable interrupts.
movs r1, 0 movs r1, 0
strh r1, [r3, #OFFSET_REG_IME - 0x200] strh r1, [r3, OFFSET_REG_IME - 0x200]
ldr r3, pool_SerialRegs ldr r3, pool_SerialRegs
@ -528,14 +619,14 @@ GameCubeMultiBoot_Quit: @ 82DF012
strh r1, [r3, OFFSET_REG_IE - 0x200] strh r1, [r3, OFFSET_REG_IE - 0x200]
@ Restore IME register. @ Restore IME register.
strh r2, [r3, #OFFSET_REG_IME - 0x200] strh r2, [r3, OFFSET_REG_IME - 0x200]
bx lr bx lr
thumb_func_end GameCubeMultiBoot_Quit thumb_func_end GameCubeMultiBoot_Quit
.align 2, 0 .align 2, 0
_082DF034: .4byte 0x4000 GameCubeMultiBoot_MaximumImageSizeUInt32s: .4byte 0x4000
pool_InterruptRegs: .4byte REG_BASE + 0x200 pool_InterruptRegs: .4byte REG_BASE + 0x200

View File

@ -1832,9 +1832,9 @@ u32 GetLinkRecvQueueLength(void)
return gLink.recvQueue.count; return gLink.recvQueue.count;
} }
bool32 IsLinkRecvQueueLengthAtLeast3(void) bool32 IsLinkRecvQueueAtOverworldMax(void)
{ {
if (GetLinkRecvQueueLength() > 2) if (GetLinkRecvQueueLength() >= OVERWORLD_RECV_QUEUE_MAX)
return TRUE; return TRUE;
return FALSE; return FALSE;

View File

@ -593,10 +593,8 @@ static bool8 MailReadBuildGraphics(void)
} }
break; break;
case 15: case 15:
if (Overworld_LinkRecvQueueLengthMoreThan2() == TRUE) if (Overworld_IsRecvQueueAtMax() == TRUE)
{
return FALSE; return FALSE;
}
break; break;
case 16: case 16:
SetVBlankCallback(VBlankCB_MailRead); SetVBlankCallback(VBlankCB_MailRead);
@ -641,7 +639,7 @@ static void CB2_InitMailRead(void)
SetMainCallback2(CB2_MailRead); SetMainCallback2(CB2_MailRead);
break; break;
} }
} while (MenuHelpers_LinkSomething() != TRUE); } while (MenuHelpers_IsLinkActive() != TRUE);
} }
static void BufferMailText(void) static void BufferMailText(void)

View File

@ -278,51 +278,45 @@ u8 GetLRKeysPressedAndHeld(void)
bool8 IsHoldingItemAllowed(u16 itemId) bool8 IsHoldingItemAllowed(u16 itemId)
{ {
// Enigma Berry can't be held in link areas // Enigma Berry can't be held in link areas
if (itemId != ITEM_ENIGMA_BERRY) if (itemId == ITEM_ENIGMA_BERRY
return TRUE; && ((gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(TRADE_CENTER)
else if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(TRADE_CENTER)
&& gSaveBlock1Ptr->location.mapNum == MAP_NUM(TRADE_CENTER)) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(TRADE_CENTER))
|| InUnionRoom() == TRUE))
return FALSE; return FALSE;
else if (InUnionRoom() != TRUE)
return TRUE;
else else
return FALSE; return TRUE;
} }
bool8 IsWritingMailAllowed(u16 itemId) bool8 IsWritingMailAllowed(u16 itemId)
{ {
if (IsUpdateLinkStateCBActive() != TRUE && InUnionRoom() != TRUE) if ((IsOverworldLinkActive() == TRUE || InUnionRoom() == TRUE) && ItemIsMail(itemId) == TRUE)
return FALSE;
else
return TRUE; return TRUE;
else if (ItemIsMail(itemId) != TRUE) }
bool8 MenuHelpers_IsLinkActive(void)
{
if (IsOverworldLinkActive() == TRUE || gReceivedRemoteLinkPlayers == 1)
return TRUE; return TRUE;
else else
return FALSE; return FALSE;
} }
bool8 MenuHelpers_LinkSomething(void) static bool8 IsActiveOverworldLinkBusy(void)
{ {
if (IsUpdateLinkStateCBActive() == TRUE || gReceivedRemoteLinkPlayers == 1) if (!MenuHelpers_IsLinkActive())
return TRUE;
else
return FALSE; return FALSE;
else
return Overworld_IsRecvQueueAtMax();
} }
static bool8 sub_81221D0(void) bool8 MenuHelpers_ShouldWaitForLinkRecv(void)
{ {
if (!MenuHelpers_LinkSomething()) if (IsActiveOverworldLinkBusy() == TRUE || IsLinkRecvQueueAtOverworldMax() == TRUE )
return FALSE;
else
return Overworld_LinkRecvQueueLengthMoreThan2();
}
bool8 MenuHelpers_CallLinkSomething(void)
{
if (sub_81221D0() == TRUE)
return TRUE; return TRUE;
else if (IsLinkRecvQueueLengthAtLeast3() != TRUE)
return FALSE;
else else
return TRUE; return FALSE;
} }
void SetItemListPerPageCount(struct ItemSlot *slots, u8 slotsCount, u8 *pageItems, u8 *totalItems, u8 maxPerPage) void SetItemListPerPageCount(struct ItemSlot *slots, u8 slotsCount, u8 *pageItems, u8 *totalItems, u8 maxPerPage)

View File

@ -136,8 +136,8 @@ static const u8 sTileBitAttributes[] =
[MB_BRIDGE_OVER_POND_MED_EDGE_2] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE), [MB_BRIDGE_OVER_POND_MED_EDGE_2] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
[MB_BRIDGE_OVER_POND_HIGH_EDGE_1] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE), [MB_BRIDGE_OVER_POND_HIGH_EDGE_1] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
[MB_BRIDGE_OVER_POND_HIGH_EDGE_2] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE), [MB_BRIDGE_OVER_POND_HIGH_EDGE_2] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
[MB_UNUSED_BRIDGE_1] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE), [MB_UNUSED_BRIDGE] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
[MB_UNUSED_BRIDGE_2] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE), [MB_BIKE_BRIDGE_OVER_BARRIER] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
[MB_COUNTER] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE), [MB_COUNTER] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
[MB_UNUSED_81] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE), [MB_UNUSED_81] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
[MB_UNUSED_82] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE), [MB_UNUSED_82] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
@ -208,7 +208,7 @@ static const u8 sTileBitAttributes[] =
[MB_HOLDS_LARGE_DECORATION] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE), [MB_HOLDS_LARGE_DECORATION] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
[MB_SECRET_BASE_TV_SHIELD] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE), [MB_SECRET_BASE_TV_SHIELD] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
[MB_PLAYER_ROOM_PC_ON] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE), [MB_PLAYER_ROOM_PC_ON] = TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
[MB_C6] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE), [MB_SECRET_BASE_DECORATION_BASE] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
[MB_SECRET_BASE_POSTER] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE), [MB_SECRET_BASE_POSTER] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
[MB_UNUSED_C8] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE), [MB_UNUSED_C8] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
[MB_UNUSED_C9] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE), [MB_UNUSED_C9] = TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
@ -711,9 +711,9 @@ bool8 MetatileBehavior_IsSecretBaseImpassable(u8 metatileBehavior)
return FALSE; return FALSE;
} }
bool8 MetatileBehavior_IsMB_C6(u8 metatileBehavior) bool8 MetatileBehavior_IsSecretBaseDecorationBase(u8 metatileBehavior)
{ {
if (metatileBehavior == MB_C6) if (metatileBehavior == MB_SECRET_BASE_DECORATION_BASE)
return TRUE; return TRUE;
else else
return FALSE; return FALSE;
@ -901,8 +901,8 @@ bool8 MetatileBehavior_IsBridgeOverWater(u8 metatileBehavior)
|| metatileBehavior == MB_BRIDGE_OVER_POND_HIGH) || metatileBehavior == MB_BRIDGE_OVER_POND_HIGH)
|| (metatileBehavior == MB_BRIDGE_OVER_POND_HIGH_EDGE_1 || (metatileBehavior == MB_BRIDGE_OVER_POND_HIGH_EDGE_1
|| metatileBehavior == MB_BRIDGE_OVER_POND_HIGH_EDGE_2 || metatileBehavior == MB_BRIDGE_OVER_POND_HIGH_EDGE_2
|| metatileBehavior == MB_UNUSED_BRIDGE_1 || metatileBehavior == MB_UNUSED_BRIDGE
|| metatileBehavior == MB_UNUSED_BRIDGE_2)) || metatileBehavior == MB_BIKE_BRIDGE_OVER_BARRIER))
return TRUE; return TRUE;
else else
return FALSE; return FALSE;
@ -1262,12 +1262,11 @@ bool8 MetatileBehavior_IsAquaHideoutWarp(u8 metatileBehavior)
return FALSE; return FALSE;
} }
// Very odd, used to initiate a teleport-style warp. bool8 MetatileBehavior_IsUnionRoomWarp(u8 metatileBehavior)
// No warp events seem to be on a metatile of this kind, and it's
// used by log bridges over ocean-style water, which wouldn't make
// sense to have a warp like this.
bool8 MetatileBehavior_IsBridgeOverOcean(u8 metatileBehavior)
{ {
// This metatile behavior is re-used for some reason by
// the Union Room exit metatile. This function is used to
// initiate a teleport-style warp.
if (metatileBehavior == MB_BRIDGE_OVER_OCEAN) if (metatileBehavior == MB_BRIDGE_OVER_OCEAN)
return TRUE; return TRUE;
else else

View File

@ -447,7 +447,7 @@ static bool32 RunMinigameCountdownDigitsAnim(u8 spriteId)
switch (sprite->sState) switch (sprite->sState)
{ {
case 0: case 0:
sub_8007E18(sprite, 0x800, 0x1A); SetSpriteMatrixAnchor(sprite, NO_ANCHOR, 26);
sprite->sState++; sprite->sState++;
// fallthrough // fallthrough
case 1: case 1:

View File

@ -20,14 +20,11 @@
#include "decompress.h" #include "decompress.h"
#include "constants/rgb.h" #include "constants/rgb.h"
// this file's functions
static void CB2_MysteryEventMenu(void); static void CB2_MysteryEventMenu(void);
static void PrintMysteryMenuText(u8 windowId, const u8 *text, u8 x, u8 y, s32 speed); static void PrintMysteryMenuText(u8 windowId, const u8 *text, u8 x, u8 y, s32 speed);
// EWRAM vars static EWRAM_DATA u8 sUnused = 0; // set but unused
static EWRAM_DATA u8 sUnknown_0203BCF8 = 0; // set but unused
// const rom data
static const struct BgTemplate sBgTemplates[] = static const struct BgTemplate sBgTemplates[] =
{ {
{ {
@ -270,7 +267,7 @@ static void CB2_MysteryEventMenu(void)
if (!IsTextPrinterActive(0)) if (!IsTextPrinterActive(0))
{ {
gMain.state++; gMain.state++;
sUnknown_0203BCF8 = 0; sUnused = 0;
} }
break; break;
case 14: case 14:

View File

@ -347,7 +347,7 @@ static const struct ListMenuTemplate sListMenu_Receive = {
.cursorKind = 0 .cursorKind = 0
}; };
static const u8 *const Unref_082F0710[] = { static const u8 *const sUnusedMenuTexts[] = {
gText_VarietyOfEventsImportedWireless, gText_VarietyOfEventsImportedWireless,
gText_WonderCardsInPossession, gText_WonderCardsInPossession,
gText_ReadNewsThatArrived, gText_ReadNewsThatArrived,

View File

@ -166,7 +166,7 @@ static void ResetPlayerHeldKeys(u16 *);
static u16 KeyInterCB_SelfIdle(u32); static u16 KeyInterCB_SelfIdle(u32);
static u16 KeyInterCB_DeferToEventScript(u32); static u16 KeyInterCB_DeferToEventScript(u32);
static u16 GetDirectionForDpadKey(u16); static u16 GetDirectionForDpadKey(u16);
static void CB1_UpdateLinkState(void); static void CB1_OverworldLink(void);
static void SetKeyInterceptCallback(u16 (*func)(u32)); static void SetKeyInterceptCallback(u16 (*func)(u32));
static void SetFieldVBlankCallback(void); static void SetFieldVBlankCallback(void);
static void FieldClearVBlankHBlankCallbacks(void); static void FieldClearVBlankHBlankCallbacks(void);
@ -1417,9 +1417,9 @@ static void ResetSafariZoneFlag_(void)
ResetSafariZoneFlag(); ResetSafariZoneFlag();
} }
bool32 IsUpdateLinkStateCBActive(void) bool32 IsOverworldLinkActive(void)
{ {
if (gMain.callback1 == CB1_UpdateLinkState) if (gMain.callback1 == CB1_OverworldLink)
return TRUE; return TRUE;
else else
return FALSE; return FALSE;
@ -1606,7 +1606,7 @@ static void CB2_LoadMapOnReturnToFieldCableClub(void)
if (LoadMapInStepsLink(&gMain.state)) if (LoadMapInStepsLink(&gMain.state))
{ {
SetFieldVBlankCallback(); SetFieldVBlankCallback();
SetMainCallback1(CB1_UpdateLinkState); SetMainCallback1(CB1_OverworldLink);
ResetAllMultiplayerState(); ResetAllMultiplayerState();
SetMainCallback2(CB2_Overworld); SetMainCallback2(CB2_Overworld);
} }
@ -1614,7 +1614,7 @@ static void CB2_LoadMapOnReturnToFieldCableClub(void)
void CB2_ReturnToField(void) void CB2_ReturnToField(void)
{ {
if (IsUpdateLinkStateCBActive() == TRUE) if (IsOverworldLinkActive() == TRUE)
{ {
SetMainCallback2(CB2_ReturnToFieldLink); SetMainCallback2(CB2_ReturnToFieldLink);
} }
@ -1636,7 +1636,7 @@ static void CB2_ReturnToFieldLocal(void)
static void CB2_ReturnToFieldLink(void) static void CB2_ReturnToFieldLink(void)
{ {
if (!Overworld_LinkRecvQueueLengthMoreThan2() && ReturnToFieldLink(&gMain.state)) if (!Overworld_IsRecvQueueAtMax() && ReturnToFieldLink(&gMain.state))
SetMainCallback2(CB2_Overworld); SetMainCallback2(CB2_Overworld);
} }
@ -1644,7 +1644,7 @@ void CB2_ReturnToFieldFromMultiplayer(void)
{ {
FieldClearVBlankHBlankCallbacks(); FieldClearVBlankHBlankCallbacks();
StopMapMusic(); StopMapMusic();
SetMainCallback1(CB1_UpdateLinkState); SetMainCallback1(CB1_OverworldLink);
ResetAllMultiplayerState(); ResetAllMultiplayerState();
if (gWirelessCommType != 0) if (gWirelessCommType != 0)
@ -2226,7 +2226,7 @@ static void CreateLinkPlayerSprites(void)
} }
static void CB1_UpdateLinkState(void) static void CB1_OverworldLink(void)
{ {
if (gWirelessCommType == 0 || !IsRfuRecvQueueEmpty() || !IsSendingKeysToLink()) if (gWirelessCommType == 0 || !IsRfuRecvQueueEmpty() || !IsSendingKeysToLink())
{ {
@ -2442,7 +2442,7 @@ static void UpdateHeldKeyCode(u16 key)
if (gWirelessCommType != 0 if (gWirelessCommType != 0
&& GetLinkSendQueueLength() > 1 && GetLinkSendQueueLength() > 1
&& IsUpdateLinkStateCBActive() == TRUE && IsOverworldLinkActive() == TRUE
&& IsSendingKeysToLink() == TRUE) && IsSendingKeysToLink() == TRUE)
{ {
switch (key) switch (key)
@ -2541,7 +2541,7 @@ static u16 KeyInterCB_DeferToEventScript(u32 key)
static u16 KeyInterCB_DeferToRecvQueue(u32 key) static u16 KeyInterCB_DeferToRecvQueue(u32 key)
{ {
u16 retVal; u16 retVal;
if (GetLinkRecvQueueLength() > 2) if (GetLinkRecvQueueLength() >= OVERWORLD_RECV_QUEUE_MAX)
{ {
retVal = LINK_KEY_CODE_EMPTY; retVal = LINK_KEY_CODE_EMPTY;
} }
@ -2613,7 +2613,7 @@ static u16 KeyInterCB_WaitForPlayersToExit(u32 keyOrPlayerId)
{ {
// keyOrPlayerId could be any keycode. This callback does no sanity checking // keyOrPlayerId could be any keycode. This callback does no sanity checking
// on the size of the key. It's assuming that it is being called from // on the size of the key. It's assuming that it is being called from
// CB1_UpdateLinkState. // CB1_OverworldLink.
if (sPlayerLinkStates[keyOrPlayerId] != PLAYER_LINK_STATE_EXITING_ROOM) if (sPlayerLinkStates[keyOrPlayerId] != PLAYER_LINK_STATE_EXITING_ROOM)
CheckRfuKeepAliveTimer(); CheckRfuKeepAliveTimer();
if (AreAllPlayersInLinkState(PLAYER_LINK_STATE_EXITING_ROOM) == TRUE) if (AreAllPlayersInLinkState(PLAYER_LINK_STATE_EXITING_ROOM) == TRUE)
@ -2834,11 +2834,11 @@ static void RunTerminateLinkScript(void)
ScriptContext2_Enable(); ScriptContext2_Enable();
} }
bool32 Overworld_LinkRecvQueueLengthMoreThan2(void) bool32 Overworld_IsRecvQueueAtMax(void)
{ {
if (!IsUpdateLinkStateCBActive()) if (!IsOverworldLinkActive())
return FALSE; return FALSE;
if (GetLinkRecvQueueLength() >= 3) if (GetLinkRecvQueueLength() >= OVERWORLD_RECV_QUEUE_MAX)
sReceivingFromLink = TRUE; sReceivingFromLink = TRUE;
else else
sReceivingFromLink = FALSE; sReceivingFromLink = FALSE;
@ -2849,9 +2849,9 @@ bool32 Overworld_RecvKeysFromLinkIsRunning(void)
{ {
u8 temp; u8 temp;
if (GetLinkRecvQueueLength() < 2) if (GetLinkRecvQueueLength() < OVERWORLD_RECV_QUEUE_MAX - 1)
return FALSE; return FALSE;
else if (IsUpdateLinkStateCBActive() != TRUE) else if (IsOverworldLinkActive() != TRUE)
return FALSE; return FALSE;
else if (IsSendingKeysToLink() != TRUE) else if (IsSendingKeysToLink() != TRUE)
return FALSE; return FALSE;
@ -2875,7 +2875,7 @@ bool32 Overworld_SendKeysToLinkIsRunning(void)
{ {
if (GetLinkSendQueueLength() < 2) if (GetLinkSendQueueLength() < 2)
return FALSE; return FALSE;
else if (IsUpdateLinkStateCBActive() != TRUE) else if (IsOverworldLinkActive() != TRUE)
return FALSE; return FALSE;
else if (IsSendingKeysToLink() != TRUE) else if (IsSendingKeysToLink() != TRUE)
return FALSE; return FALSE;

View File

@ -439,7 +439,7 @@ void UpdatePulseBlend(struct PulseBlend *pulseBlend)
} }
// Below used for the Roulette grid // Below used for the Roulette grid
void ClearTilemapRect(u16 *dest, u16 src, u8 left, u8 top, u8 width, u8 height) void FillTilemapRect(u16 *dest, u16 value, u8 left, u8 top, u8 width, u8 height)
{ {
u16 *_dest; u16 *_dest;
u8 i; u8 i;
@ -450,9 +450,7 @@ void ClearTilemapRect(u16 *dest, u16 src, u8 left, u8 top, u8 width, u8 height)
{ {
_dest = dest + i * 32; _dest = dest + i * 32;
for (j = 0; j < width; j++) for (j = 0; j < width; j++)
{ *_dest++ = value;
*_dest++ = src;
}
} }
} }
@ -468,8 +466,39 @@ void SetTilemapRect(u16 *dest, u16 *src, u8 left, u8 top, u8 width, u8 height)
{ {
_dest = dest + i * 32; _dest = dest + i * 32;
for (j = 0; j < width; j++) for (j = 0; j < width; j++)
{
*_dest++ = *_src++; *_dest++ = *_src++;
} }
} }
static void FillTilemapRect_Unused(void *dest, u16 value, u8 left, u8 top, u8 width, u8 height)
{
u8 i, j;
u8 x, y;
for (i = 0, y = top; i < height; i++)
{
for (x = left, j = 0; j < width; j++)
{
*(u16 *)((dest) + (y * 64 + x * 2)) = value;
x = (x + 1) % 32;
}
y = (y + 1) % 32;
}
}
static void SetTilemapRect_Unused(void *dest, const u16 *src, u8 left, u8 top, u8 width, u8 height)
{
u8 i, j;
u8 x, y;
const u16 *_src;
for (i = 0, _src = src, y = top; i < height; i++)
{
for (x = left, j = 0; j < width; j++)
{
*(u16 *)((dest) + (y * 64 + x * 2)) = *(_src++);
x = (x + 1) % 32;
}
y = (y + 1) % 32;
}
} }

View File

@ -476,7 +476,7 @@ static void CB2_InitPartyMenu(void)
{ {
while (TRUE) while (TRUE)
{ {
if (MenuHelpers_CallLinkSomething() == TRUE || ShowPartyMenu() == TRUE || MenuHelpers_LinkSomething() == TRUE) if (MenuHelpers_ShouldWaitForLinkRecv() == TRUE || ShowPartyMenu() == TRUE || MenuHelpers_IsLinkActive() == TRUE)
break; break;
} }
} }
@ -509,7 +509,7 @@ static bool8 ShowPartyMenu(void)
gMain.state++; gMain.state++;
break; break;
case 5: case 5:
if (!MenuHelpers_LinkSomething()) if (!MenuHelpers_IsLinkActive())
ResetTasks(); ResetTasks();
gMain.state++; gMain.state++;
break; break;
@ -1182,7 +1182,7 @@ u8 GetPartyMenuType(void)
void Task_HandleChooseMonInput(u8 taskId) void Task_HandleChooseMonInput(u8 taskId)
{ {
if (!gPaletteFade.active && MenuHelpers_CallLinkSomething() != TRUE) if (!gPaletteFade.active && MenuHelpers_ShouldWaitForLinkRecv() != TRUE)
{ {
s8 *slotPtr = GetCurrentPartySlotPtr(); s8 *slotPtr = GetCurrentPartySlotPtr();
@ -1319,7 +1319,7 @@ static void HandleChooseMonCancel(u8 taskId, s8 *slotPtr)
PlaySE(SE_SELECT); PlaySE(SE_SELECT);
if (DisplayCancelChooseMonYesNo(taskId) != TRUE) if (DisplayCancelChooseMonYesNo(taskId) != TRUE)
{ {
if (!MenuHelpers_LinkSomething()) if (!MenuHelpers_IsLinkActive())
gSpecialVar_0x8004 = PARTY_SIZE + 1; gSpecialVar_0x8004 = PARTY_SIZE + 1;
gPartyMenuUseExitCallback = FALSE; gPartyMenuUseExitCallback = FALSE;
*slotPtr = PARTY_SIZE + 1; *slotPtr = PARTY_SIZE + 1;
@ -1659,7 +1659,7 @@ bool8 IsPartyMenuTextPrinterActive(void)
static void Task_WaitForLinkAndReturnToChooseMon(u8 taskId) static void Task_WaitForLinkAndReturnToChooseMon(u8 taskId)
{ {
if (MenuHelpers_CallLinkSomething() != TRUE) if (MenuHelpers_ShouldWaitForLinkRecv() != TRUE)
{ {
DisplayPartyMenuStdMessage(PARTY_MSG_CHOOSE_MON); DisplayPartyMenuStdMessage(PARTY_MSG_CHOOSE_MON);
gTasks[taskId].func = Task_HandleChooseMonInput; gTasks[taskId].func = Task_HandleChooseMonInput;
@ -1672,7 +1672,7 @@ static void Task_ReturnToChooseMonAfterText(u8 taskId)
{ {
ClearStdWindowAndFrameToTransparent(6, 0); ClearStdWindowAndFrameToTransparent(6, 0);
ClearWindowTilemap(6); ClearWindowTilemap(6);
if (MenuHelpers_LinkSomething() == TRUE) if (MenuHelpers_IsLinkActive() == TRUE)
{ {
gTasks[taskId].func = Task_WaitForLinkAndReturnToChooseMon; gTasks[taskId].func = Task_WaitForLinkAndReturnToChooseMon;
} }
@ -2663,7 +2663,7 @@ static void Task_TryCreateSelectionWindow(u8 taskId)
static void Task_HandleSelectionMenuInput(u8 taskId) static void Task_HandleSelectionMenuInput(u8 taskId)
{ {
if (!gPaletteFade.active && MenuHelpers_CallLinkSomething() != TRUE) if (!gPaletteFade.active && MenuHelpers_ShouldWaitForLinkRecv() != TRUE)
{ {
s8 input; s8 input;
s16 *data = gTasks[taskId].data; s16 *data = gTasks[taskId].data;
@ -3634,7 +3634,7 @@ static void CursorCb_FieldMove(u8 taskId)
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]); PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]); PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
if (MenuHelpers_LinkSomething() == TRUE || InUnionRoom() == TRUE) if (MenuHelpers_IsLinkActive() == TRUE || InUnionRoom() == TRUE)
{ {
if (fieldMove == FIELD_MOVE_MILK_DRINK || fieldMove == FIELD_MOVE_SOFT_BOILED) if (fieldMove == FIELD_MOVE_MILK_DRINK || fieldMove == FIELD_MOVE_SOFT_BOILED)
DisplayPartyMenuStdMessage(PARTY_MSG_CANT_USE_HERE); DisplayPartyMenuStdMessage(PARTY_MSG_CANT_USE_HERE);

View File

@ -505,11 +505,11 @@ static void CB2_InitPokeblockMenu(void)
{ {
while (1) while (1)
{ {
if (MenuHelpers_CallLinkSomething() == TRUE) if (MenuHelpers_ShouldWaitForLinkRecv() == TRUE)
break; break;
if (InitPokeblockMenu() == TRUE) if (InitPokeblockMenu() == TRUE)
break; break;
if (MenuHelpers_LinkSomething() == TRUE) if (MenuHelpers_IsLinkActive() == TRUE)
break; break;
} }
} }
@ -1004,7 +1004,7 @@ static void Task_HandlePokeblockMenuInput(u8 taskId)
{ {
s16 *data = gTasks[taskId].data; s16 *data = gTasks[taskId].data;
if (!gPaletteFade.active && MenuHelpers_CallLinkSomething() != TRUE) if (!gPaletteFade.active && MenuHelpers_ShouldWaitForLinkRecv() != TRUE)
{ {
if (JOY_NEW(SELECT_BUTTON)) if (JOY_NEW(SELECT_BUTTON))
{ {
@ -1057,7 +1057,7 @@ static void Task_HandlePokeblocksSwapInput(u8 taskId)
{ {
s16 *data = gTasks[taskId].data; s16 *data = gTasks[taskId].data;
if (MenuHelpers_CallLinkSomething() == TRUE) if (MenuHelpers_ShouldWaitForLinkRecv() == TRUE)
return; return;
if (JOY_NEW(SELECT_BUTTON)) if (JOY_NEW(SELECT_BUTTON))
@ -1161,7 +1161,7 @@ static void Task_HandlePokeblockActionsInput(u8 taskId)
{ {
s8 itemId; s8 itemId;
if (MenuHelpers_CallLinkSomething() == TRUE) if (MenuHelpers_ShouldWaitForLinkRecv() == TRUE)
return; return;
itemId = Menu_ProcessInputNoWrap(); itemId = Menu_ProcessInputNoWrap();

View File

@ -688,11 +688,11 @@ void PreparePokeblockFeedScene(void)
{ {
while (1) while (1)
{ {
if (MenuHelpers_CallLinkSomething() == TRUE) if (MenuHelpers_ShouldWaitForLinkRecv() == TRUE)
break; break;
if (LoadPokeblockFeedScene() == TRUE) if (LoadPokeblockFeedScene() == TRUE)
break; break;
if (MenuHelpers_LinkSomething() == TRUE) if (MenuHelpers_IsLinkActive() == TRUE)
break; break;
} }
} }

View File

@ -3197,7 +3197,7 @@ static void LoadPokeJumpGfx(void)
FillBgTilemapBufferRect_Palette0(BG_INTERFACE, 0, 0, 0, 0x20, 0x20); FillBgTilemapBufferRect_Palette0(BG_INTERFACE, 0, 0, 0, 0x20, 0x20);
PrintScoreSuffixes(); PrintScoreSuffixes();
PrintScore(0); PrintScore(0);
sub_8098C6C(0, 1, 0xE0); LoadUserWindowBorderGfxOnBg(0, 1, 0xE0);
CopyBgTilemapBufferToVram(BG_INTERFACE); CopyBgTilemapBufferToVram(BG_INTERFACE);
CopyBgTilemapBufferToVram(BG_VENUSAUR); CopyBgTilemapBufferToVram(BG_VENUSAUR);
CopyBgTilemapBufferToVram(BG_BONUSES); CopyBgTilemapBufferToVram(BG_BONUSES);

View File

@ -1146,7 +1146,7 @@ static void VBlank(void)
static void CB2_InitSummaryScreen(void) static void CB2_InitSummaryScreen(void)
{ {
while (MenuHelpers_CallLinkSomething() != TRUE && LoadGraphics() != TRUE && MenuHelpers_LinkSomething() != TRUE); while (MenuHelpers_ShouldWaitForLinkRecv() != TRUE && LoadGraphics() != TRUE && MenuHelpers_IsLinkActive() != TRUE);
} }
static bool8 LoadGraphics(void) static bool8 LoadGraphics(void)
@ -1490,7 +1490,7 @@ static void BeginCloseSummaryScreen(u8 taskId)
static void CloseSummaryScreen(u8 taskId) static void CloseSummaryScreen(u8 taskId)
{ {
if (MenuHelpers_CallLinkSomething() != TRUE && !gPaletteFade.active) if (MenuHelpers_ShouldWaitForLinkRecv() != TRUE && !gPaletteFade.active)
{ {
SetMainCallback2(sMonSummaryScreen->callback); SetMainCallback2(sMonSummaryScreen->callback);
gLastViewedMonIndex = sMonSummaryScreen->curMonIndex; gLastViewedMonIndex = sMonSummaryScreen->curMonIndex;
@ -1508,7 +1508,7 @@ static void CloseSummaryScreen(u8 taskId)
static void Task_HandleInput(u8 taskId) static void Task_HandleInput(u8 taskId)
{ {
if (MenuHelpers_CallLinkSomething() != TRUE && !gPaletteFade.active) if (MenuHelpers_ShouldWaitForLinkRecv() != TRUE && !gPaletteFade.active)
{ {
if (JOY_NEW(DPAD_UP)) if (JOY_NEW(DPAD_UP))
{ {
@ -1660,7 +1660,7 @@ static void Task_ChangeSummaryMon(u8 taskId)
gSprites[sMonSummaryScreen->spriteIds[SPRITE_ARR_ID_MON]].data[2] = 0; gSprites[sMonSummaryScreen->spriteIds[SPRITE_ARR_ID_MON]].data[2] = 0;
break; break;
default: default:
if (MenuHelpers_CallLinkSomething() == 0 && FuncIsActiveTask(Task_ShowStatusWindow) == 0) if (!MenuHelpers_ShouldWaitForLinkRecv() && !FuncIsActiveTask(Task_ShowStatusWindow))
{ {
data[0] = 0; data[0] = 0;
gTasks[taskId].func = Task_HandleInput; gTasks[taskId].func = Task_HandleInput;
@ -1889,7 +1889,7 @@ static void Task_HandleInput_MoveSelect(u8 taskId)
{ {
s16 *data = gTasks[taskId].data; s16 *data = gTasks[taskId].data;
if (MenuHelpers_CallLinkSomething() != 1) if (MenuHelpers_ShouldWaitForLinkRecv() != TRUE)
{ {
if (JOY_NEW(DPAD_UP)) if (JOY_NEW(DPAD_UP))
{ {
@ -2029,7 +2029,7 @@ static void Task_HandleInput_MovePositionSwitch(u8 taskId)
{ {
s16* data = gTasks[taskId].data; s16* data = gTasks[taskId].data;
if (MenuHelpers_CallLinkSomething() != TRUE) if (MenuHelpers_ShouldWaitForLinkRecv() != TRUE)
{ {
if (JOY_NEW(DPAD_UP)) if (JOY_NEW(DPAD_UP))
{ {
@ -2170,7 +2170,7 @@ static void Task_HandleReplaceMoveInput(u8 taskId)
{ {
s16* data = gTasks[taskId].data; s16* data = gTasks[taskId].data;
if (MenuHelpers_CallLinkSomething() != TRUE) if (MenuHelpers_ShouldWaitForLinkRecv() != TRUE)
{ {
if (gPaletteFade.active != TRUE) if (gPaletteFade.active != TRUE)
{ {

View File

@ -212,7 +212,7 @@ u32 CreateLoopedTask(LoopedTask loopedTask, u32 priority)
{ {
u16 taskId; u16 taskId;
if (!IsUpdateLinkStateCBActive()) if (!IsOverworldLinkActive())
taskId = CreateTask(Task_RunLoopedTask, priority); taskId = CreateTask(Task_RunLoopedTask, priority);
else else
taskId = CreateTask(Task_RunLoopedTask_LinkMode, priority); taskId = CreateTask(Task_RunLoopedTask_LinkMode, priority);
@ -288,7 +288,7 @@ static void Task_RunLoopedTask_LinkMode(u8 taskId)
s16 *state; s16 *state;
u32 action; u32 action;
if (Overworld_LinkRecvQueueLengthMoreThan2()) if (Overworld_IsRecvQueueAtMax())
return; return;
task = (LoopedTask)GetWordTaskArg(taskId, 1); task = (LoopedTask)GetWordTaskArg(taskId, 1);

View File

@ -6,6 +6,7 @@
#include "bg.h" #include "bg.h"
#include "menu.h" #include "menu.h"
#include "decompress.h" #include "decompress.h"
#include "international_string_util.h"
// TODO: This UI isnt just for match call, seems to be the general pokenav list UI // TODO: This UI isnt just for match call, seems to be the general pokenav list UI
@ -66,8 +67,6 @@ struct PokenavSub17
u32 loopedTaskId; u32 loopedTaskId;
}; };
extern void sub_81DB620(u32 windowId, u32 a1, u32 a2, u32 a3, u32 a4);
void sub_81C82E4(struct PokenavSub17 *matchCall); void sub_81C82E4(struct PokenavSub17 *matchCall);
bool32 CopyPokenavListMenuTemplate(struct PokenavSub17Substruct *a0, const struct BgTemplate *a1, struct PokenavListTemplate *a2, s32 a3); bool32 CopyPokenavListMenuTemplate(struct PokenavSub17Substruct *a0, const struct BgTemplate *a1, struct PokenavListTemplate *a2, s32 a3);
void InitMatchCallWindowState(struct MatchCallWindowState *a0, struct PokenavListTemplate *a1); void InitMatchCallWindowState(struct MatchCallWindowState *a0, struct PokenavListTemplate *a1);
@ -754,9 +753,8 @@ static void PrintMatchCallFlavorText(struct MatchCallWindowState *a0, struct Pok
if (str != NULL) if (str != NULL)
{ {
sub_81DB620(list->listWindow.windowId, 1, r6 * 2, list->listWindow.unk4 - 1, 2); FillWindowTilesByRow(list->listWindow.windowId, 1, r6 * 2, list->listWindow.unk4 - 1, 2);
AddTextPrinterParameterized(list->listWindow.windowId, FONT_NARROW, str, 2, (r6 << 4) + 1, TEXT_SKIP_DRAW, NULL); AddTextPrinterParameterized(list->listWindow.windowId, FONT_NARROW, str, 2, (r6 << 4) + 1, TEXT_SKIP_DRAW, NULL);
CopyWindowRectToVram(list->listWindow.windowId, COPYWIN_GFX, 0, r6 * 2, list->listWindow.unk4, 2);
} }
} }

View File

@ -1317,28 +1317,28 @@ static void UpdateGridSelectionRect(u8 selectionId)
switch (selectionId) switch (selectionId)
{ {
case SELECTION_NONE: case SELECTION_NONE:
ClearTilemapRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13); FillTilemapRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13);
break; break;
case COL_WYNAUT: case COL_WYNAUT:
case COL_AZURILL: case COL_AZURILL:
case COL_SKITTY: case COL_SKITTY:
case COL_MAKUHITA: case COL_MAKUHITA:
temp0 = (selectionId * 3 + 14); temp0 = (selectionId * 3 + 14);
ClearTilemapRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13); FillTilemapRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13);
SetTilemapRect(&sRoulette->tilemapBuffers[0][0], &sRoulette->gridTilemap[281], temp0, 7, 3, 13); SetTilemapRect(&sRoulette->tilemapBuffers[0][0], &sRoulette->gridTilemap[281], temp0, 7, 3, 13);
break; break;
case ROW_ORANGE: case ROW_ORANGE:
case ROW_GREEN: case ROW_GREEN:
case ROW_PURPLE: case ROW_PURPLE:
temp1 = ((selectionId - 1) / 5 * 3 + 10); temp1 = ((selectionId - 1) / 5 * 3 + 10);
ClearTilemapRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13); FillTilemapRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13);
SetTilemapRect(&sRoulette->tilemapBuffers[0][0], &sRoulette->gridTilemap[320], 14, temp1, 16, 3); SetTilemapRect(&sRoulette->tilemapBuffers[0][0], &sRoulette->gridTilemap[320], 14, temp1, 16, 3);
break; break;
// Individual square // Individual square
default: default:
temp0 = GET_COL(selectionId) * 3 + 14; temp0 = GET_COL(selectionId) * 3 + 14;
temp1 = ((selectionId - 1) / 5 * 3 + 7); temp1 = ((selectionId - 1) / 5 * 3 + 7);
ClearTilemapRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13); FillTilemapRect(&sRoulette->tilemapBuffers[0][0], 0, 14, 7, 16, 13);
SetTilemapRect(&sRoulette->tilemapBuffers[0][0], &sRoulette->gridTilemap[272], temp0, temp1, 3, 3); SetTilemapRect(&sRoulette->tilemapBuffers[0][0], &sRoulette->gridTilemap[272], temp0, temp1, 3, 3);
break; break;
} }

View File

@ -1208,7 +1208,7 @@ bool8 ScrCmd_turnvobject(struct ScriptContext *ctx)
// The player is frozen after waiting for their current movement to finish. // The player is frozen after waiting for their current movement to finish.
bool8 ScrCmd_lockall(struct ScriptContext *ctx) bool8 ScrCmd_lockall(struct ScriptContext *ctx)
{ {
if (IsUpdateLinkStateCBActive()) if (IsOverworldLinkActive())
{ {
return FALSE; return FALSE;
} }
@ -1224,7 +1224,7 @@ bool8 ScrCmd_lockall(struct ScriptContext *ctx)
// The player and selected object are frozen after waiting for their current movement to finish. // The player and selected object are frozen after waiting for their current movement to finish.
bool8 ScrCmd_lock(struct ScriptContext *ctx) bool8 ScrCmd_lock(struct ScriptContext *ctx)
{ {
if (IsUpdateLinkStateCBActive()) if (IsOverworldLinkActive())
{ {
return FALSE; return FALSE;
} }
@ -2197,7 +2197,7 @@ bool8 ScrCmd_selectapproachingtrainer(struct ScriptContext *ctx)
bool8 ScrCmd_lockfortrainer(struct ScriptContext *ctx) bool8 ScrCmd_lockfortrainer(struct ScriptContext *ctx)
{ {
if (IsUpdateLinkStateCBActive()) if (IsOverworldLinkActive())
{ {
return FALSE; return FALSE;
} }

View File

@ -251,7 +251,7 @@ static void BuildStartMenuActions(void)
{ {
sNumStartMenuActions = 0; sNumStartMenuActions = 0;
if (IsUpdateLinkStateCBActive() == TRUE) if (IsOverworldLinkActive() == TRUE)
{ {
BuildLinkModeStartMenu(); BuildLinkModeStartMenu();
} }
@ -554,7 +554,7 @@ void Task_ShowStartMenu(u8 taskId)
void ShowStartMenu(void) void ShowStartMenu(void)
{ {
if (!IsUpdateLinkStateCBActive()) if (!IsOverworldLinkActive())
{ {
FreezeObjectEvents(); FreezeObjectEvents();
PlayerFreeze(); PlayerFreeze();
@ -679,7 +679,7 @@ static bool8 StartMenuPlayerNameCallback(void)
RemoveExtraStartMenuWindows(); RemoveExtraStartMenuWindows();
CleanupOverworldWindowsAndTilemaps(); CleanupOverworldWindowsAndTilemaps();
if (IsUpdateLinkStateCBActive() || InUnionRoom()) if (IsOverworldLinkActive() || InUnionRoom())
ShowPlayerTrainerCard(CB2_ReturnToFieldWithOpenMenu); // Display trainer card ShowPlayerTrainerCard(CB2_ReturnToFieldWithOpenMenu); // Display trainer card
else if (FlagGet(FLAG_SYS_FRONTIER_PASS)) else if (FlagGet(FLAG_SYS_FRONTIER_PASS))
ShowFrontierPass(CB2_ReturnToFieldWithOpenMenu); // Display frontier pass ShowFrontierPass(CB2_ReturnToFieldWithOpenMenu); // Display frontier pass

View File

@ -6,7 +6,6 @@
#include "bg.h" #include "bg.h"
#include "graphics.h" #include "graphics.h"
// const rom data
const u8 gTextWindowFrame1_Gfx[] = INCBIN_U8("graphics/text_window/1.4bpp"); const u8 gTextWindowFrame1_Gfx[] = INCBIN_U8("graphics/text_window/1.4bpp");
static const u8 sTextWindowFrame2_Gfx[] = INCBIN_U8("graphics/text_window/2.4bpp"); static const u8 sTextWindowFrame2_Gfx[] = INCBIN_U8("graphics/text_window/2.4bpp");
static const u8 sTextWindowFrame3_Gfx[] = INCBIN_U8("graphics/text_window/3.4bpp"); static const u8 sTextWindowFrame3_Gfx[] = INCBIN_U8("graphics/text_window/3.4bpp");
@ -190,7 +189,8 @@ const u16 *GetOverworldTextboxPalettePtr(void)
return gMessageBox_Pal; return gMessageBox_Pal;
} }
void sub_8098C6C(u8 bg, u16 destOffset, u8 palOffset) // Effectively LoadUserWindowBorderGfx but specifying the bg directly instead of a window from that bg
void LoadUserWindowBorderGfxOnBg(u8 bg, u16 destOffset, u8 palOffset)
{ {
LoadBgTiles(bg, sWindowFrames[gSaveBlock2Ptr->optionsWindowFrameType].tiles, 0x120, destOffset); LoadBgTiles(bg, sWindowFrames[gSaveBlock2Ptr->optionsWindowFrameType].tiles, 0x120, destOffset);
LoadPalette(GetWindowFrameTilesPal(gSaveBlock2Ptr->optionsWindowFrameType)->pal, palOffset, 0x20); LoadPalette(GetWindowFrameTilesPal(gSaveBlock2Ptr->optionsWindowFrameType)->pal, palOffset, 0x20);

View File

@ -456,7 +456,7 @@ static void Task_TrainerCard(u8 taskId)
} }
break; break;
case STATE_WAIT_FLIP_TO_BACK: case STATE_WAIT_FLIP_TO_BACK:
if (IsCardFlipTaskActive() && Overworld_LinkRecvQueueLengthMoreThan2() != TRUE) if (IsCardFlipTaskActive() && Overworld_IsRecvQueueAtMax() != TRUE)
{ {
PlaySE(SE_RG_CARD_OPEN); PlaySE(SE_RG_CARD_OPEN);
sData->mainState = STATE_HANDLE_INPUT_BACK; sData->mainState = STATE_HANDLE_INPUT_BACK;
@ -513,7 +513,7 @@ static void Task_TrainerCard(u8 taskId)
CloseTrainerCard(taskId); CloseTrainerCard(taskId);
break; break;
case STATE_WAIT_FLIP_TO_FRONT: case STATE_WAIT_FLIP_TO_FRONT:
if (IsCardFlipTaskActive() && Overworld_LinkRecvQueueLengthMoreThan2() != TRUE) if (IsCardFlipTaskActive() && Overworld_IsRecvQueueAtMax() != TRUE)
{ {
sData->mainState = STATE_HANDLE_INPUT_FRONT; sData->mainState = STATE_HANDLE_INPUT_FRONT;
PlaySE(SE_RG_CARD_OPEN); PlaySE(SE_RG_CARD_OPEN);
@ -1663,7 +1663,7 @@ static bool8 Task_AnimateCardFlipDown(struct Task* task)
static bool8 Task_DrawFlippedCardSide(struct Task* task) static bool8 Task_DrawFlippedCardSide(struct Task* task)
{ {
sData->allowDMACopy = FALSE; sData->allowDMACopy = FALSE;
if (Overworld_LinkRecvQueueLengthMoreThan2() == TRUE) if (Overworld_IsRecvQueueAtMax() == TRUE)
return FALSE; return FALSE;
do do

View File

@ -249,7 +249,7 @@ static void SetBgTilemapBuffers(void);
static void ClearBg0(void); static void ClearBg0(void);
static void LoadChatWindowBorderGfx(void); static void LoadChatWindowBorderGfx(void);
static void LoadChatWindowGfx(void); static void LoadChatWindowGfx(void);
static void sub_8020680(void); static void LoadChatUnkPalette(void);
static void LoadChatMessagesWindow(void); static void LoadChatMessagesWindow(void);
static void LoadKeyboardWindow(void); static void LoadKeyboardWindow(void);
static void LoadKeyboardSwapWindow(void); static void LoadKeyboardSwapWindow(void);
@ -1983,10 +1983,10 @@ static int GetShouldShowCaseToggleIcon(void)
{ {
u8 *str = GetLastCharOfMessagePtr(); u8 *str = GetLastCharOfMessagePtr();
u32 character = *str; u32 character = *str;
if (character > 0xFF || sCaseToggleTable[character] == character || sCaseToggleTable[character] == 0) if (character > EOS || sCaseToggleTable[character] == character || sCaseToggleTable[character] == CHAR_SPACE)
return 3; return 3; // Don't show
else else
return 0; return 0; // Show
} }
static u8 *GetChatHostName(void) static u8 *GetChatHostName(void)
@ -2246,7 +2246,7 @@ static bool32 Display_LoadGfx(u8 *state)
LoadChatWindowGfx(); LoadChatWindowGfx();
break; break;
case 4: case 4:
sub_8020680(); LoadChatUnkPalette();
break; break;
case 5: case 5:
LoadChatMessagesWindow(); LoadChatMessagesWindow();
@ -3074,7 +3074,7 @@ static void LoadChatWindowGfx(void)
CopyBgTilemapBufferToVram(2); CopyBgTilemapBufferToVram(2);
} }
static void sub_8020680(void) static void LoadChatUnkPalette(void)
{ {
LoadPalette(sUnk_Palette1, 0x80, sizeof(sUnk_Palette1)); LoadPalette(sUnk_Palette1, 0x80, sizeof(sUnk_Palette1));
RequestDma3Fill(0, (void *)BG_CHAR_ADDR(1) + 0x20, 0x20, 1); RequestDma3Fill(0, (void *)BG_CHAR_ADDR(1) + 0x20, 0x20, 1);