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)) #define SAFE_DIV(a, b) ((a) / (b))
#endif #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 // Extracts the upper 16 bits of a 32-bit number
#define HIHALF(n) (((n) & 0xFFFF0000) >> 16) #define HIHALF(n) (((n) & 0xFFFF0000) >> 16)

View file

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

View file

@ -38,7 +38,7 @@
#include "constants/moves.h" #include "constants/moves.h"
#include "constants/trainers.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[]; extern const struct MapLayout *const gMapLayouts[];
@ -1904,7 +1904,7 @@ static void GetPyramidFloorLayoutOffsets(u8 *layoutOffsets)
for (i = 0; i < NUM_PYRAMID_FLOOR_SQUARES; i++) 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; rand >>= 3;
if (i == 7) if (i == 7)
{ {

View file

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

View file

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

View file

@ -326,7 +326,7 @@ u8 ContestAI_GetActionToUse(void)
{ {
// Randomly choose a move index. If it's the move // Randomly choose a move index. If it's the move
// with the highest (or tied highest) score, return // 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]; u8 score = eContestAI.moveScores[moveIdx];
int i; int i;
for (i = 0; i < MAX_MON_MOVES; 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) static void Task_Scene1_Load(u8 taskId)
{ {
SetVBlankCallback(NULL); SetVBlankCallback(NULL);
sIntroCharacterGender = Random() & 1; sIntroCharacterGender = MOD(Random(), GENDER_COUNT);
IntroResetGpuRegs(); IntroResetGpuRegs();
SetGpuReg(REG_OFFSET_BG3VOFS, 0); SetGpuReg(REG_OFFSET_BG3VOFS, 0);
SetGpuReg(REG_OFFSET_BG2VOFS, 80); 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) if (sprite->sDelay == 0 || --sprite->sDelay == 0)
{ {
sprite->sDelay = 8; 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]; sprite->x2 = x[sprite->sXPosId];
} }
@ -1097,7 +1097,7 @@ static void SpriteCB_Underscore(struct Sprite *sprite)
sprite->sDelay++; sprite->sDelay++;
if (sprite->sDelay > 8) 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; sprite->sDelay = 0;
} }
} }