mirror of
https://github.com/pret/pokeemerald.git
synced 2026-09-28 04:46:53 -05:00
Merge branch 'upcoming' into ghoulsaveblock
This commit is contained in:
@@ -54,7 +54,8 @@ struct __attribute__((packed, aligned(2))) BattleMoveEffect
|
||||
const u8 *battleScript;
|
||||
u16 battleTvScore:3;
|
||||
u16 encourageEncore:1;
|
||||
u16 flags:12; // coming soon...
|
||||
u16 semiInvulnerableEffect:1;
|
||||
u16 flags:11; // coming soon...
|
||||
};
|
||||
|
||||
#define GET_MOVE_BATTLESCRIPT(move) gBattleMoveEffects[gMovesInfo[move].effect].battleScript
|
||||
@@ -846,10 +847,10 @@ struct BattleScripting
|
||||
s32 bideDmg;
|
||||
u8 multihitString[6];
|
||||
bool8 expOnCatch;
|
||||
u8 twoTurnsMoveStringId;
|
||||
u8 unused;
|
||||
u8 animArg1;
|
||||
u8 animArg2;
|
||||
u16 tripleKickPower;
|
||||
u16 savedStringId;
|
||||
u8 moveendState;
|
||||
u8 savedStatChanger; // For further use, if attempting to change stat two times(ex. Moody)
|
||||
u8 shiftSwitched; // When the game tells you the next enemy's pokemon and you switch. Option for noobs but oh well.
|
||||
|
||||
@@ -108,7 +108,7 @@ bool32 IsStatLoweringMoveEffect(u32 moveEffect);
|
||||
bool32 IsMoveRedirectionPrevented(u32 move, u32 atkAbility);
|
||||
bool32 IsMoveEncouragedToHit(u32 battlerAtk, u32 battlerDef, u32 move);
|
||||
bool32 IsHazardMoveEffect(u32 moveEffect);
|
||||
bool32 IsChargingMove(u32 battlerAtk, u32 effect);
|
||||
bool32 IsTwoTurnNotSemiInvulnerableMove(u32 battlerAtk, u32 move);
|
||||
void ProtectChecks(u32 battlerAtk, u32 battlerDef, u32 move, u32 predictedMove, s32 *score);
|
||||
bool32 ShouldSetSandstorm(u32 battler, u32 ability, u32 holdEffect);
|
||||
bool32 ShouldSetHail(u32 battler, u32 ability, u32 holdEffect);
|
||||
|
||||
@@ -417,6 +417,7 @@ extern const struct OamData gOamData_AffineDouble_ObjNormal_64x64;
|
||||
extern const struct OamData gOamData_AffineDouble_ObjBlend_64x64;
|
||||
extern const struct OamData gOamData_AffineDouble_ObjBlend_64x32;
|
||||
extern const struct OamData gOamData_AffineDouble_ObjNormal_8x16;
|
||||
extern const struct OamData gOamData_AffineDouble_ObjNormal_64x32;
|
||||
extern const struct OamData gOamData_AffineOff_ObjBlend_16x16;
|
||||
extern const struct OamData gOamData_AffineDouble_ObjBlend_16x16;
|
||||
extern const struct OamData gOamData_AffineNormal_ObjNormal_8x8;
|
||||
|
||||
@@ -611,7 +611,6 @@ extern const u8 BattleScript_EffectSleepTalk[];
|
||||
extern const u8 BattleScript_EffectDestinyBond[];
|
||||
extern const u8 BattleScript_EffectSpite[];
|
||||
extern const u8 BattleScript_EffectHealBell[];
|
||||
extern const u8 BattleScript_EffectTripleKick[];
|
||||
extern const u8 BattleScript_EffectMeanLook[];
|
||||
extern const u8 BattleScript_EffectNightmare[];
|
||||
extern const u8 BattleScript_EffectMinimize[];
|
||||
|
||||
@@ -225,6 +225,7 @@ bool32 MoveHasMoveEffect(u32 move, u32 moveEffect);
|
||||
bool32 MoveHasMoveEffectWithChance(u32 move, u32 moveEffect, u32 chance);
|
||||
bool32 MoveHasMoveEffectSelf(u32 move, u32 moveEffect);
|
||||
bool32 MoveHasMoveEffectSelfArg(u32 move, u32 moveEffect, u32 argument);
|
||||
bool32 MoveHasChargeTurnMoveEffect(u32 move);
|
||||
|
||||
bool32 CanSleep(u32 battler);
|
||||
bool32 CanBePoisoned(u32 battlerAttacker, u32 battlerTarget);
|
||||
|
||||
@@ -179,15 +179,15 @@
|
||||
|
||||
// Var Settings
|
||||
// To use the following features in scripting, replace the 0s with the var ID you're assigning it to.
|
||||
// Eg: Replace with VAR_UNUSED_0x40F7 so you can use VAR_TERRAIN for that feature.
|
||||
#define VAR_TERRAIN 0 // If this var has a value, assigning a STATUS_FIELD_xx_TERRAIN to it before battle causes the battle to start with that terrain active
|
||||
// Eg: Replace with VAR_UNUSED_0x40F7 so you can use B_VAR_TERRAIN for that feature.
|
||||
#define B_VAR_TERRAIN 0 // If this var has a value, assigning a STATUS_FIELD_xx_TERRAIN to it before battle causes the battle to start with that terrain active.
|
||||
#define B_VAR_TERRAIN_TIMER 0 // If this var has a value greater or equal than 1 field terrains will last that number of turns, otherwise they will last until they're overwritten.
|
||||
#define B_VAR_WILD_AI_FLAGS 0 // If not 0, you can use this var to add to default wild AI flags. NOT usable with flags above (1 << 15)
|
||||
|
||||
// Sky Battles
|
||||
#define B_FLAG_SKY_BATTLE 0 // If this flag has a value, the player will be able to engage in scripted Sky Battles.
|
||||
#define B_VAR_SKY_BATTLE 0 // If this var has a value, the game will remember the positions of Pokémon used in Sky Battles.
|
||||
|
||||
#define B_SKY_BATTLE_STRICT_ELIGIBILITY FALSE //If TRUE, Sky Battles will use the eligibility from Pokémon XY. If FALSE, all Flying-types or Pokémon with Levitate are allowed.
|
||||
#define B_FLAG_SKY_BATTLE 0 // If this flag has a value, the player will be able to engage in scripted Sky Battles.
|
||||
#define B_VAR_SKY_BATTLE 0 // If this var has a value, the game will remember the positions of Pokémon used in Sky Battles.
|
||||
#define B_SKY_BATTLE_STRICT_ELIGIBILITY FALSE // If TRUE, Sky Battles will use the eligibility from Pokémon XY. If FALSE, all Flying-types or Pokémon with Levitate are allowed.
|
||||
|
||||
// Flag and Var settings
|
||||
#define B_RESET_FLAGS_VARS_AFTER_WHITEOUT TRUE // If TRUE, Overworld_ResetBattleFlagsAndVars will reset battle-related Flags and Vars when the player whites out.
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
#define STATUS2_FLINCHED (1 << 3)
|
||||
#define STATUS2_UPROAR (1 << 4 | 1 << 5 | 1 << 6)
|
||||
#define STATUS2_UPROAR_TURN(num) ((num) << 4)
|
||||
#define STATUS2_UNUSED (1 << 7)
|
||||
#define STATUS2_TORMENT (1 << 7)
|
||||
#define STATUS2_BIDE (1 << 8 | 1 << 9)
|
||||
#define STATUS2_BIDE_TURN(num) (((num) << 8) & STATUS2_BIDE)
|
||||
#define STATUS2_LOCK_CONFUSE (1 << 10 | 1 << 11) // e.g. Thrash
|
||||
@@ -139,7 +139,7 @@
|
||||
#define STATUS2_POWDER (1 << 14)
|
||||
#define STATUS2_INFATUATION (1 << 16 | 1 << 17 | 1 << 18 | 1 << 19) // 4 bits, one for every battler
|
||||
#define STATUS2_INFATUATED_WITH(battler) (gBitTable[battler] << 16)
|
||||
#define STATUS2_FOCUS_ENERGY (1 << 20)
|
||||
#define STATUS2_DEFENSE_CURL (1 << 20)
|
||||
#define STATUS2_TRANSFORMED (1 << 21)
|
||||
#define STATUS2_RECHARGE (1 << 22)
|
||||
#define STATUS2_RAGE (1 << 23)
|
||||
@@ -149,8 +149,9 @@
|
||||
#define STATUS2_NIGHTMARE (1 << 27)
|
||||
#define STATUS2_CURSED (1 << 28)
|
||||
#define STATUS2_FORESIGHT (1 << 29)
|
||||
#define STATUS2_DEFENSE_CURL (1 << 30)
|
||||
#define STATUS2_TORMENT (1 << 31)
|
||||
#define STATUS2_DRAGON_CHEER (1 << 30)
|
||||
#define STATUS2_FOCUS_ENERGY (1 << 31)
|
||||
#define STATUS2_FOCUS_ENERGY_ANY (STATUS2_DRAGON_CHEER | STATUS2_FOCUS_ENERGY)
|
||||
|
||||
#define STATUS3_LEECHSEED_BATTLER (1 << 0 | 1 << 1) // The battler to receive HP from Leech Seed
|
||||
#define STATUS3_LEECHSEED (1 << 2)
|
||||
|
||||
@@ -414,8 +414,8 @@
|
||||
|
||||
// Below are used by AnimTask_ShakeMon2 and AnimTask_SetGrayscaleOrOriginalPal
|
||||
#define ANIM_PLAYER_LEFT (MAX_BATTLERS_COUNT + 0)
|
||||
#define ANIM_PLAYER_RIGHT (MAX_BATTLERS_COUNT + 1)
|
||||
#define ANIM_OPPONENT_LEFT (MAX_BATTLERS_COUNT + 2)
|
||||
#define ANIM_OPPONENT_LEFT (MAX_BATTLERS_COUNT + 1)
|
||||
#define ANIM_PLAYER_RIGHT (MAX_BATTLERS_COUNT + 2)
|
||||
#define ANIM_OPPONENT_RIGHT (MAX_BATTLERS_COUNT + 3)
|
||||
#define ANIM_ATTACKER_FORCE (MAX_BATTLERS_COUNT + 4)
|
||||
|
||||
|
||||
@@ -117,10 +117,8 @@ enum {
|
||||
EFFECT_BELLY_DRUM,
|
||||
EFFECT_PSYCH_UP,
|
||||
EFFECT_MIRROR_COAT,
|
||||
EFFECT_SKULL_BASH,
|
||||
EFFECT_EARTHQUAKE,
|
||||
EFFECT_FUTURE_SIGHT,
|
||||
EFFECT_GUST,
|
||||
EFFECT_SOLAR_BEAM,
|
||||
EFFECT_THUNDER,
|
||||
EFFECT_TELEPORT,
|
||||
@@ -172,7 +170,6 @@ enum {
|
||||
EFFECT_WEATHER_BALL,
|
||||
EFFECT_TICKLE,
|
||||
EFFECT_COSMIC_POWER,
|
||||
EFFECT_SKY_UPPERCUT,
|
||||
EFFECT_BULK_UP,
|
||||
EFFECT_WATER_SPORT,
|
||||
EFFECT_CALM_MIND,
|
||||
@@ -318,7 +315,6 @@ enum {
|
||||
EFFECT_BOLT_BEAK,
|
||||
EFFECT_SKY_DROP,
|
||||
EFFECT_EXPANDING_FORCE,
|
||||
EFFECT_METEOR_BEAM,
|
||||
EFFECT_RISING_VOLTAGE,
|
||||
EFFECT_BEAK_BLAST,
|
||||
EFFECT_COURT_CHANGE,
|
||||
@@ -352,6 +348,7 @@ enum {
|
||||
EFFECT_RAIN_ALWAYS_HIT, // Unlike EFFECT_THUNDER, it doesn't get its accuracy reduced under sun.
|
||||
EFFECT_SHED_TAIL,
|
||||
EFFECT_UPPER_HAND,
|
||||
EFFECT_DRAGON_CHEER,
|
||||
NUM_BATTLE_MOVE_EFFECTS,
|
||||
};
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
#define sBIDE_DMG (gBattleScripting + 0x04) // bideDmg
|
||||
#define sMULTIHIT_STRING (gBattleScripting + 0x08) // multihitString
|
||||
#define sEXP_CATCH (gBattleScripting + 0x0E) // expOnCatch
|
||||
#define sTWOTURN_STRINGID (gBattleScripting + 0x0F) // twoTurnsMoveStringId
|
||||
#define sUNUSED (gBattleScripting + 0x0F) // unused
|
||||
#define sB_ANIM_ARG1 (gBattleScripting + 0x10) // animArg1
|
||||
#define sB_ANIM_ARG2 (gBattleScripting + 0x11) // animArg2
|
||||
#define sTRIPLE_KICK_POWER (gBattleScripting + 0x12) // tripleKickPower
|
||||
#define sSAVED_STRINID (gBattleScripting + 0x12) // savedStringId
|
||||
#define sMOVEEND_STATE (gBattleScripting + 0x14) // moveendState
|
||||
#define sSAVED_STAT_CHANGER (gBattleScripting + 0x15) // savedStatChanger
|
||||
#define sSHIFT_SWITCHED (gBattleScripting + 0x16) // shiftSwitched
|
||||
@@ -181,7 +181,7 @@
|
||||
#define VARIOUS_TRY_FAIRY_LOCK 89
|
||||
#define VARIOUS_JUMP_IF_NO_ALLY 90
|
||||
#define VARIOUS_POISON_TYPE_IMMUNITY 91
|
||||
#define VARIOUS_JUMP_IF_NO_HOLD_EFFECT 92
|
||||
#define VARIOUS_JUMP_IF_HOLD_EFFECT 92
|
||||
#define VARIOUS_INFATUATE_WITH_BATTLER 93
|
||||
#define VARIOUS_SET_LAST_USED_ITEM 94
|
||||
#define VARIOUS_PARALYZE_TYPE_IMMUNITY 95
|
||||
@@ -220,25 +220,24 @@
|
||||
#define VARIOUS_SET_SKY_DROP 128
|
||||
#define VARIOUS_CLEAR_SKY_DROP 129
|
||||
#define VARIOUS_SKY_DROP_YAWN 130
|
||||
#define VARIOUS_JUMP_IF_HOLD_EFFECT 131
|
||||
#define VARIOUS_CURE_CERTAIN_STATUSES 132
|
||||
#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 133
|
||||
#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 134
|
||||
#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 135
|
||||
#define VARIOUS_SAVE_BATTLER_ITEM 136
|
||||
#define VARIOUS_RESTORE_BATTLER_ITEM 137
|
||||
#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 138
|
||||
#define VARIOUS_SET_BEAK_BLAST 139
|
||||
#define VARIOUS_SWAP_SIDE_STATUSES 140
|
||||
#define VARIOUS_SWAP_STATS 141
|
||||
#define VARIOUS_TEATIME_INVUL 142
|
||||
#define VARIOUS_TEATIME_TARGETS 143
|
||||
#define VARIOUS_TRY_WIND_RIDER_POWER 144
|
||||
#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 145
|
||||
#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 146
|
||||
#define VARIOUS_STORE_HEALING_WISH 147
|
||||
#define VARIOUS_HIT_SWITCH_TARGET_FAILED 148
|
||||
#define VARIOUS_TRY_REVIVAL_BLESSING 149
|
||||
#define VARIOUS_CURE_CERTAIN_STATUSES 131
|
||||
#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 132
|
||||
#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 133
|
||||
#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 134
|
||||
#define VARIOUS_SAVE_BATTLER_ITEM 135
|
||||
#define VARIOUS_RESTORE_BATTLER_ITEM 136
|
||||
#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 137
|
||||
#define VARIOUS_SET_BEAK_BLAST 138
|
||||
#define VARIOUS_SWAP_SIDE_STATUSES 139
|
||||
#define VARIOUS_SWAP_STATS 140
|
||||
#define VARIOUS_TEATIME_INVUL 141
|
||||
#define VARIOUS_TEATIME_TARGETS 142
|
||||
#define VARIOUS_TRY_WIND_RIDER_POWER 143
|
||||
#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 144
|
||||
#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 145
|
||||
#define VARIOUS_STORE_HEALING_WISH 146
|
||||
#define VARIOUS_HIT_SWITCH_TARGET_FAILED 147
|
||||
#define VARIOUS_TRY_REVIVAL_BLESSING 148
|
||||
|
||||
// Cmd_manipulatedamage
|
||||
#define DMG_CHANGE_SIGN 0
|
||||
|
||||
@@ -697,13 +697,14 @@
|
||||
#define STRINGID_THESWAMPDISAPPEARED 695
|
||||
#define STRINGID_PKMNTELLCHILLINGRECEPTIONJOKE 696
|
||||
#define STRINGID_HOSPITALITYRESTORATION 697
|
||||
#define STRINGID_ELECTROSHOCKCHARGING 698
|
||||
#define STRINGID_ELECTROSHOTCHARGING 698
|
||||
#define STRINGID_ITEMWASUSEDUP 699
|
||||
#define STRINGID_ATTACKERLOSTITSTYPE 700
|
||||
#define STRINGID_SHEDITSTAIL 701
|
||||
#define STRINGID_SUPERSWEETAROMAWAFTS 702
|
||||
#define STRINGID_CLOAKEDINAHARSHLIGHT 702
|
||||
#define STRINGID_SUPERSWEETAROMAWAFTS 703
|
||||
|
||||
#define BATTLESTRINGS_COUNT 703
|
||||
#define BATTLESTRINGS_COUNT 704
|
||||
|
||||
// This is the string id that gBattleStringsTable starts with.
|
||||
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
|
||||
@@ -747,22 +748,6 @@
|
||||
#define B_MSG_LEECH_SEED_DRAIN 3
|
||||
#define B_MSG_LEECH_SEED_OOZE 4
|
||||
|
||||
// gFirstTurnOfTwoStringIds
|
||||
#define B_MSG_TURN1_RAZOR_WIND 0
|
||||
#define B_MSG_TURN1_SOLAR_BEAM 1
|
||||
#define B_MSG_TURN1_SKULL_BASH 2
|
||||
#define B_MSG_TURN1_SKY_ATTACK 3
|
||||
#define B_MSG_TURN1_FLY 4
|
||||
#define B_MSG_TURN1_DIG 5
|
||||
#define B_MSG_TURN1_DIVE 6
|
||||
#define B_MSG_TURN1_BOUNCE 7
|
||||
#define B_MSG_TURN1_PHANTOM_FORCE 8
|
||||
#define B_MSG_TURN1_GEOMANCY 9
|
||||
#define B_MSG_TURN1_FREEZE_SHOCK 10
|
||||
#define B_MSG_TURN1_SKY_DROP 11
|
||||
#define B_MSG_TURN1_METEOR_BEAM 12
|
||||
#define B_MSG_TURN1_ELECTRO_SHOCK 13
|
||||
|
||||
// gMoveWeatherChangeStringIds
|
||||
#define B_MSG_STARTED_RAIN 0
|
||||
#define B_MSG_STARTED_DOWNPOUR 1
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#define EXPANSION_VERSION_MAJOR 1
|
||||
#define EXPANSION_VERSION_MINOR 7
|
||||
#define EXPANSION_VERSION_PATCH 2
|
||||
#define EXPANSION_VERSION_PATCH 3
|
||||
|
||||
// FALSE if this this version of Expansion is not a tagged commit, i.e.
|
||||
// it contains unreleased changes.
|
||||
|
||||
@@ -123,6 +123,7 @@ extern const union AffineAnimCmd *const gAffineAnims_BattleSpriteContest[];
|
||||
extern const union AnimCmd sAnim_GeneralFrame0[];
|
||||
extern const union AnimCmd sAnim_GeneralFrame3[];
|
||||
extern const union AnimCmd *const gAnims_MonPic[];
|
||||
extern const union AnimCmd *const sAnims_Trainer[];
|
||||
extern const struct TrainerSprite gTrainerSprites[];
|
||||
extern const struct TrainerBacksprite gTrainerBacksprites[];
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "config.h" // we need to define config before gba headers as print stuff needs the functions nulled before defines.
|
||||
#include "gba/gba.h"
|
||||
#include "fpmath.h"
|
||||
#include "metaprogram.h"
|
||||
#include "constants/global.h"
|
||||
#include "constants/flags.h"
|
||||
#include "constants/vars.h"
|
||||
@@ -66,7 +67,7 @@
|
||||
// Used in cases where division by 0 can occur in the retail version.
|
||||
// Avoids invalid opcodes on some emulators, and the otherwise UB.
|
||||
#ifdef UBFIX
|
||||
#define SAFE_DIV(a, b) ((b) ? (a) / (b) : 0)
|
||||
#define SAFE_DIV(a, b) (((b) != 0) ? (a) / (b) : 0)
|
||||
#else
|
||||
#define SAFE_DIV(a, b) ((a) / (b))
|
||||
#endif
|
||||
@@ -124,22 +125,6 @@
|
||||
#define NUM_FLAG_BYTES ROUND_BITS_TO_BYTES(FLAGS_COUNT)
|
||||
#define NUM_TRENDY_SAYING_BYTES ROUND_BITS_TO_BYTES(NUM_TRENDY_SAYINGS)
|
||||
|
||||
// Calls m0/m1/.../m8 depending on how many arguments are passed.
|
||||
#define VARARG_8(m, ...) CAT(m, NARG_8(__VA_ARGS__))(__VA_ARGS__)
|
||||
|
||||
// This returns the number of arguments passed to it (up to 8).
|
||||
#define NARG_8(...) NARG_8_(_, ##__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0)
|
||||
#define NARG_8_(_, a, b, c, d, e, f, g, h, N, ...) N
|
||||
|
||||
#define CAT(a, b) CAT_(a, b)
|
||||
#define CAT_(a, b) a ## b
|
||||
|
||||
#define STR(...) STR_(__VA_ARGS__)
|
||||
#define STR_(...) #__VA_ARGS__
|
||||
|
||||
// Converts a string to a compound literal, essentially making it a pointer to const u8
|
||||
#define COMPOUND_STRING(str) (const u8[]) _(str)
|
||||
|
||||
// This produces an error at compile-time if expr is zero.
|
||||
// It looks like file.c:line: size of array `id' is negative
|
||||
#define STATIC_ASSERT(expr, id) typedef char id[(expr) ? 1 : -1];
|
||||
|
||||
134
include/metaprogram.h
Normal file
134
include/metaprogram.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/* Macros to aid with metaprogramming. */
|
||||
#ifndef METAPROGRAM_H
|
||||
#define METAPROGRAM_H
|
||||
|
||||
/* Calls m0/m1/.../m8 depending on how many arguments are passed. */
|
||||
#define VARARG_8(m, ...) CAT(m, NARG_8(__VA_ARGS__))(__VA_ARGS__)
|
||||
|
||||
/* Returns the number of arguments passed to it (up to 8). */
|
||||
#define NARG_8(...) NARG_8_(_, ##__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0)
|
||||
#define NARG_8_(_, a, b, c, d, e, f, g, h, N, ...) N
|
||||
|
||||
/* Expands 'a' and 'b' and then concatenates them. */
|
||||
#define CAT(a, b) CAT_(a, b)
|
||||
#define CAT_(a, b) a ## b
|
||||
|
||||
/* Expands '__VA_ARGS__' and then stringizes them. */
|
||||
#define STR(...) STR_(__VA_ARGS__)
|
||||
#define STR_(...) #__VA_ARGS__
|
||||
|
||||
/* Converts a string to a compound literal, essentially making it a pointer to const u8 */
|
||||
#define COMPOUND_STRING(str) (const u8[]) _(str)
|
||||
|
||||
/* Expands to the first/second/third/fourth argument. */
|
||||
#define FIRST(a, ...) a
|
||||
#define SECOND(a, ...) __VA_OPT__(FIRST(__VA_ARGS__))
|
||||
#define THIRD(a, ...) __VA_OPT__(SECOND(__VA_ARGS__))
|
||||
#define FOURTH(a, ...) __VA_OPT__(THIRD(__VA_ARGS__))
|
||||
|
||||
/* Expands to everything but the first x arguments */
|
||||
#define EXCEPT_1(a, ...) __VA_OPT__(__VA_ARGS__)
|
||||
#define EXCEPT_2(a, ...) __VA_OPT__(EXCEPT_1(__VA_ARGS__))
|
||||
#define EXCEPT_3(a, ...) __VA_OPT__(EXCEPT_2(__VA_ARGS__))
|
||||
#define EXCEPT_4(a, ...) __VA_OPT__(EXCEPT_3(__VA_ARGS__))
|
||||
|
||||
/* 'UNPACK (x, y, z)' expands to 'x, y, z'.
|
||||
* Useful for passing arguments which may contain commas into a macro. */
|
||||
#define UNPACK(...) __VA_ARGS__
|
||||
|
||||
/* Expands to 'macro(...args, ...)'. */
|
||||
#define INVOKE_WITH(macro, args, ...) INVOKE_WITH_(macro, UNPACK args __VA_OPT__(, __VA_ARGS__))
|
||||
#define INVOKE_WITH_(macro, ...) macro(__VA_ARGS__)
|
||||
|
||||
/* Recursive macros.
|
||||
* Based on https://www.scs.stanford.edu/~dm/blog/va-opt.html
|
||||
*
|
||||
* Macros prefixed with R_ are recursive, to correctly expand them the
|
||||
* top-level macro which references them should use 'RECURSIVELY' around
|
||||
* them. 'RECURSIVELY' cannot be nested, hence the top-level macro must
|
||||
* use it so that a recursive macro is able to reference another
|
||||
* recursive macro. */
|
||||
|
||||
#define RECURSIVELY(...) RECURSIVELY_4(RECURSIVELY_4(RECURSIVELY_4(RECURSIVELY_4(__VA_ARGS__))))
|
||||
#define RECURSIVELY_4(...) RECURSIVELY_3(RECURSIVELY_3(RECURSIVELY_3(RECURSIVELY_3(__VA_ARGS__))))
|
||||
#define RECURSIVELY_3(...) RECURSIVELY_2(RECURSIVELY_2(RECURSIVELY_2(RECURSIVELY_2(__VA_ARGS__))))
|
||||
#define RECURSIVELY_2(...) RECURSIVELY_1(RECURSIVELY_1(RECURSIVELY_1(RECURSIVELY_1(__VA_ARGS__))))
|
||||
#define RECURSIVELY_1(...) __VA_ARGS__
|
||||
|
||||
/* Useful for deferring expansion until the second scan. See
|
||||
* https://www.scs.stanford.edu/~dm/blog/va-opt.html for more info. */
|
||||
#define PARENS ()
|
||||
|
||||
/* Expands to 'macro(a)' for each 'a' in '...' */
|
||||
#define R_FOR_EACH(macro, ...) __VA_OPT__(R_FOR_EACH_(macro, __VA_ARGS__))
|
||||
#define R_FOR_EACH_(macro, a, ...) macro(a) __VA_OPT__(R_FOR_EACH_P PARENS (macro, __VA_ARGS__))
|
||||
#define R_FOR_EACH_P() R_FOR_EACH_
|
||||
|
||||
/* Expands to 'macro(...args, a)' for each 'a' in '...'. */
|
||||
#define R_FOR_EACH_WITH(macro, args, ...) __VA_OPT__(R_FOR_EACH_WITH_(macro, args, __VA_ARGS__))
|
||||
#define R_FOR_EACH_WITH_(macro, args, a, ...) INVOKE_WITH(macro, args, a) __VA_OPT__(R_FOR_EACH_WITH_P PARENS (macro, args, __VA_ARGS__))
|
||||
#define R_FOR_EACH_WITH_P() R_FOR_EACH_WITH_
|
||||
|
||||
/* Picks the xth VA_ARG if it exists, otherwise returns a default value */
|
||||
#define DEFAULT(_default, ...) FIRST(__VA_OPT__(__VA_ARGS__, ) _default)
|
||||
#define DEFAULT_2(_default, ...) DEFAULT(_default __VA_OPT__(, SECOND(__VA_ARGS__)))
|
||||
#define DEFAULT_3(_default, ...) DEFAULT(_default __VA_OPT__(, THIRD(__VA_ARGS__)))
|
||||
#define DEFAULT_4(_default, ...) DEFAULT(_default __VA_OPT__(, FOURTH(__VA_ARGS__)))
|
||||
|
||||
/* (Credit to MGriffin) A rather monstrous way of finding the set bit in a word.
|
||||
Invalid input causes a compiler error. Sample: https://cexplore.karathan.at/z/x1hm7B */
|
||||
#define BIT_INDEX(n) \
|
||||
(n) == (1 << 0) ? 0 : \
|
||||
(n) == (1 << 1) ? 1 : \
|
||||
(n) == (1 << 2) ? 2 : \
|
||||
(n) == (1 << 3) ? 3 : \
|
||||
(n) == (1 << 4) ? 4 : \
|
||||
(n) == (1 << 5) ? 5 : \
|
||||
(n) == (1 << 6) ? 6 : \
|
||||
(n) == (1 << 7) ? 7 : \
|
||||
(n) == (1 << 8) ? 8 : \
|
||||
(n) == (1 << 9) ? 9 : \
|
||||
(n) == (1 << 10) ? 10 : \
|
||||
(n) == (1 << 11) ? 11 : \
|
||||
(n) == (1 << 12) ? 12 : \
|
||||
(n) == (1 << 13) ? 13 : \
|
||||
(n) == (1 << 14) ? 14 : \
|
||||
(n) == (1 << 15) ? 15 : \
|
||||
(n) == (1 << 16) ? 16 : \
|
||||
(n) == (1 << 17) ? 17 : \
|
||||
(n) == (1 << 18) ? 18 : \
|
||||
(n) == (1 << 19) ? 19 : \
|
||||
(n) == (1 << 20) ? 20 : \
|
||||
(n) == (1 << 21) ? 21 : \
|
||||
(n) == (1 << 22) ? 22 : \
|
||||
(n) == (1 << 23) ? 23 : \
|
||||
(n) == (1 << 24) ? 24 : \
|
||||
(n) == (1 << 25) ? 25 : \
|
||||
(n) == (1 << 26) ? 26 : \
|
||||
(n) == (1 << 27) ? 27 : \
|
||||
(n) == (1 << 28) ? 28 : \
|
||||
(n) == (1 << 29) ? 29 : \
|
||||
(n) == (1 << 30) ? 30 : \
|
||||
(n) == (1 << 31) ? 31 : \
|
||||
*(u32 *)NULL
|
||||
|
||||
#define COMPRESS_BITS_0 0, 1
|
||||
#define COMPRESS_BITS_1 1, 1
|
||||
#define COMPRESS_BITS_2 2, 1
|
||||
#define COMPRESS_BITS_3 3, 1
|
||||
#define COMPRESS_BITS_4 4, 1
|
||||
#define COMPRESS_BITS_5 5, 1
|
||||
#define COMPRESS_BITS_6 6, 1
|
||||
#define COMPRESS_BITS_7 7, 1
|
||||
|
||||
/* Will try and compress a set bit (or up to three sequential bits) into a single byte
|
||||
Input must be of the form (upper << lower) where upper can be up to 3, lower up to 31 */
|
||||
#define COMPRESS_BITS(_val) COMPRESS_BITS_STEP_2 _val
|
||||
#define COMPRESS_BITS_STEP_2(_unpacked) COMPRESS_BITS_STEP_3(COMPRESS_BITS_## _unpacked)
|
||||
#define COMPRESS_BITS_STEP_3(...) COMPRESS_BITS_STEP_4(__VA_ARGS__)
|
||||
#define COMPRESS_BITS_STEP_4(upper, lower) (((upper % 8) << 5) + (BIT_INDEX(lower)))
|
||||
|
||||
/* Will read a compressed bit stored by COMPRESS_BIT into a single byte */
|
||||
#define UNCOMPRESS_BITS(compressed) ((compressed >> 5) << (compressed & 0x1F))
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user