Add MOD to match mod with powers of 2

This commit is contained in:
GriffinR 2023-08-16 16:44:45 -04:00
parent 057928438a
commit bdc0ea1037
8 changed files with 21 additions and 14 deletions

View file

@ -85,6 +85,12 @@
#define SAFE_DIV(a, b) ((a) / (b))
#endif
// The below macro does a%n, but (to match) will switch to a&(n-1) if n is a power of 2.
// There are cases where GF does a&(n-1) where we would really like to have a%n, because
// if n is changed to a value that isn't a power of 2 then a&(n-1) is unlikely to work as
// intended, and a%n for powers of 2 isn't always optimized to use &.
#define MOD(a, n)(((n) & ((n)-1)) ? ((a) % (n)) : ((a) & ((n)-1)))
// Extracts the upper 16 bits of a 32-bit number
#define HIHALF(n) (((n) & 0xFFFF0000) >> 16)

View file

@ -1588,7 +1588,7 @@ static void OpponentHandleChooseMove(void)
u16 move;
do
{
chosenMoveId = Random() & 3;
chosenMoveId = MOD(Random(), MAX_MON_MOVES);
move = moveInfo->moves[chosenMoveId];
} while (move == MOVE_NONE);

View file

@ -38,7 +38,7 @@
#include "constants/moves.h"
#include "constants/trainers.h"
#define NUM_LAYOUT_OFFSETS 8 // Assumed to be a power of 2
#define NUM_LAYOUT_OFFSETS 8
extern const struct MapLayout *const gMapLayouts[];
@ -1904,7 +1904,7 @@ static void GetPyramidFloorLayoutOffsets(u8 *layoutOffsets)
for (i = 0; i < NUM_PYRAMID_FLOOR_SQUARES; i++)
{
layoutOffsets[i] = sPyramidFloorTemplates[id].layoutOffsets[rand & (NUM_LAYOUT_OFFSETS - 1)];
layoutOffsets[i] = sPyramidFloorTemplates[id].layoutOffsets[MOD(rand, NUM_LAYOUT_OFFSETS)];
rand >>= 3;
if (i == 7)
{

View file

@ -7350,7 +7350,7 @@ static void Cmd_tryconversiontypechange(void)
{
do
{
while ((moveChecked = Random() & (MAX_MON_MOVES - 1)) >= validMoves);
while ((moveChecked = MOD(Random(), MAX_MON_MOVES)) >= validMoves);
moveType = gBattleMoves[gBattleMons[gBattlerAttacker].moves[moveChecked]].type;
@ -8189,7 +8189,7 @@ static void Cmd_trychoosesleeptalkmove(void)
do
{
movePosition = Random() & (MAX_MON_MOVES - 1);
movePosition = MOD(Random(), MAX_MON_MOVES);
} while ((gBitTable[movePosition] & unusableMovesBits));
gCalledMove = gBattleMons[gBattlerAttacker].moves[movePosition];

View file

@ -2773,11 +2773,12 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
{
do
{
// Pick either MOVE_EFFECT_SLEEP, MOVE_EFFECT_POISON or MOVE_EFFECT_BURN
gBattleCommunication[MOVE_EFFECT_BYTE] = Random() & 3;
} while (gBattleCommunication[MOVE_EFFECT_BYTE] == 0);
// Replace MOVE_EFFECT_BURN with MOVE_EFFECT_PARALYSIS
if (gBattleCommunication[MOVE_EFFECT_BYTE] == MOVE_EFFECT_BURN)
gBattleCommunication[MOVE_EFFECT_BYTE] += 2; // 5 MOVE_EFFECT_PARALYSIS
gBattleCommunication[MOVE_EFFECT_BYTE] += (MOVE_EFFECT_PARALYSIS - MOVE_EFFECT_BURN);
gBattleCommunication[MOVE_EFFECT_BYTE] += MOVE_EFFECT_AFFECTS_USER;
BattleScriptPushCursor();
@ -3956,7 +3957,7 @@ u8 IsMonDisobedient(void)
{
// Randomly select, then print a disobedient string
// B_MSG_LOAFING, B_MSG_WONT_OBEY, B_MSG_TURNED_AWAY, or B_MSG_PRETEND_NOT_NOTICE
gBattleCommunication[MULTISTRING_CHOOSER] = Random() & (NUM_LOAF_STRINGS - 1);
gBattleCommunication[MULTISTRING_CHOOSER] = MOD(Random(), NUM_LOAF_STRINGS);
gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround;
return 1;
}
@ -3964,7 +3965,7 @@ u8 IsMonDisobedient(void)
{
do
{
gCurrMovePos = gChosenMovePos = Random() & (MAX_MON_MOVES - 1);
gCurrMovePos = gChosenMovePos = MOD(Random(), MAX_MON_MOVES);
} while (gBitTable[gCurrMovePos] & calc);
gCalledMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos];
@ -4007,7 +4008,7 @@ u8 IsMonDisobedient(void)
{
// Randomly select, then print a disobedient string
// B_MSG_LOAFING, B_MSG_WONT_OBEY, B_MSG_TURNED_AWAY, or B_MSG_PRETEND_NOT_NOTICE
gBattleCommunication[MULTISTRING_CHOOSER] = Random() & (NUM_LOAF_STRINGS - 1);
gBattleCommunication[MULTISTRING_CHOOSER] = MOD(Random(), NUM_LOAF_STRINGS);
gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround;
return 1;
}

View file

@ -326,7 +326,7 @@ u8 ContestAI_GetActionToUse(void)
{
// Randomly choose a move index. If it's the move
// with the highest (or tied highest) score, return
u8 moveIdx = Random() & (MAX_MON_MOVES - 1); // % MAX_MON_MOVES doesn't match
u8 moveIdx = MOD(Random(), MAX_MON_MOVES);
u8 score = eContestAI.moveScores[moveIdx];
int i;
for (i = 0; i < MAX_MON_MOVES; i++)

View file

@ -1163,7 +1163,7 @@ void CB2_InitCopyrightScreenAfterTitleScreen(void)
static void Task_Scene1_Load(u8 taskId)
{
SetVBlankCallback(NULL);
sIntroCharacterGender = Random() & 1;
sIntroCharacterGender = MOD(Random(), GENDER_COUNT);
IntroResetGpuRegs();
SetGpuReg(REG_OFFSET_BG3VOFS, 0);
SetGpuReg(REG_OFFSET_BG2VOFS, 80);

View file

@ -1067,7 +1067,7 @@ static void SpriteCB_InputArrow(struct Sprite *sprite)
if (sprite->sDelay == 0 || --sprite->sDelay == 0)
{
sprite->sDelay = 8;
sprite->sXPosId = (sprite->sXPosId + 1) & (ARRAY_COUNT(x) - 1);
sprite->sXPosId = MOD(sprite->sXPosId + 1, ARRAY_COUNT(x));
}
sprite->x2 = x[sprite->sXPosId];
}
@ -1097,7 +1097,7 @@ static void SpriteCB_Underscore(struct Sprite *sprite)
sprite->sDelay++;
if (sprite->sDelay > 8)
{
sprite->sYPosId = (sprite->sYPosId + 1) & (ARRAY_COUNT(y) - 1);
sprite->sYPosId = MOD(sprite->sYPosId + 1, ARRAY_COUNT(y));
sprite->sDelay = 0;
}
}