diff --git a/include/macros.h b/include/macros.h index cfa3a6d31..f6e8eee5b 100644 --- a/include/macros.h +++ b/include/macros.h @@ -71,6 +71,8 @@ #define MODE_NTSC 0 #define MODE_MPAL 1 -#define MODE_PAL 2 +#define MODE_PAL 2 + +#define FORCE_CRASH { *(vs8*)0 = 0; } #endif // MACROS_H diff --git a/include/object_constants.h b/include/object_constants.h index e9fc6fe7d..7bd55faf5 100644 --- a/include/object_constants.h +++ b/include/object_constants.h @@ -127,42 +127,85 @@ enum DialogState { #define ACTIVE_PARTICLE_TRIANGLE (1 << 19) // 0x00080000 /* oBehParams */ + +/** + * behParams: oBehParams + * index: index of bparam in oBehParams + * val: bparam value + * num: number of bparams to read as one value + */ +// Number of bparams in oBehParams +#define NUM_BPARAMS 4 +// Number of bits in one bparam #define BPARAM_SIZE 8 -#define BPARAM_MASK BITMASK(BPARAM_SIZE) +// Number of bits in bparam bitmask +#define BPARAM_MASK_SIZE(num) (BPARAM_SIZE * (num)) +// bparam bitmask ('num' 1 -> 0xFF, 'num' 2 -> 0xFFFF, etc.) +#define BPARAM_MASK(num) BITMASK(BPARAM_MASK_SIZE(num)) +// Returns the amount of bits to shift a bparam value ('index' == bparam index) +#define BPARAM_NSHIFT(index, num) (((NUM_BPARAMS - ((num) - 1)) - (index)) * BPARAM_SIZE) +// Returns the bparam(s) value shifted to the index location in oBehParams +#define SHIFTED_BPARAM(val, index, num) (((val) & BPARAM_MASK(num)) << BPARAM_NSHIFT((index), (num))) +// Returns the bparam(s) value from the index location in oBehParams +#define GET_BPARAMS(behParams, index, num) ((behParams >> BPARAM_NSHIFT((index), (num))) & BPARAM_MASK(num)) +// bparam mask shifted to the index location in oBehParams +#define BPARAM_SHIFTED_MASK(index, num) (BPARAM_MASK(num) << BPARAM_NSHIFT((index), (num))) +// oBehParams with the specified bparam(s) cleared +#define CLEARED_BPARAM(behParams, index, num) ((behParams) & ~BPARAM_SHIFTED_MASK((index), (num))) -#define BPARAM1_MASK (BPARAM_MASK << (BPARAM_SIZE * 3)) // 0xFF000000 -#define BPARAM2_MASK (BPARAM_MASK << (BPARAM_SIZE * 2)) // 0x00FF0000 -#define BPARAM3_MASK (BPARAM_MASK << (BPARAM_SIZE * 1)) // 0x0000FF00 -#define BPARAM4_MASK (BPARAM_MASK << (BPARAM_SIZE * 0)) // 0x000000FF +// Get a u8 bparam from oBehParams +#define GET_BPARAM1(behParams) GET_BPARAMS((behParams), 1, 1) +#define GET_BPARAM2(behParams) GET_BPARAMS((behParams), 2, 1) +#define GET_BPARAM3(behParams) GET_BPARAMS((behParams), 3, 1) +#define GET_BPARAM4(behParams) GET_BPARAMS((behParams), 4, 1) -// Convert oBehParams to a bparam -#define OBEHPARAMS_TO_BPARAM(p, shift) (((p) >> (BPARAM_SIZE * (shift))) & BPARAM_MASK) +// Read 2 bparams as a single value +#define GET_BPARAM12(behParams) GET_BPARAMS((behParams), 1, 2) +#define GET_BPARAM23(behParams) GET_BPARAMS((behParams), 2, 2) +#define GET_BPARAM34(behParams) GET_BPARAMS((behParams), 3, 2) -// Read a bparam from oBehParams -#define GET_BPARAM1(p) OBEHPARAMS_TO_BPARAM((p), 3) -#define GET_BPARAM2(p) OBEHPARAMS_TO_BPARAM((p), 2) -#define GET_BPARAM3(p) OBEHPARAMS_TO_BPARAM((p), 1) -#define GET_BPARAM4(p) OBEHPARAMS_TO_BPARAM((p), 0) +// Read 3 bparams as a single value +#define GET_BPARAM123(behParams) GET_BPARAMS((behParams), 1, 3) +#define GET_BPARAM234(behParams) GET_BPARAMS((behParams), 2, 3) -// Read two bparams as a single value from oBehParams -#define GET_BPARAM12(p) (((p) & (BPARAM1_MASK | BPARAM2_MASK)) >> (BPARAM_SIZE * 2)) -#define GET_BPARAM23(p) (((p) & (BPARAM2_MASK | BPARAM3_MASK)) >> (BPARAM_SIZE * 1)) -#define GET_BPARAM34(p) (((p) & (BPARAM3_MASK | BPARAM4_MASK)) >> (BPARAM_SIZE * 0)) +// Read 4 bparams as a single value +#define GET_BPARAM1234(behParams) (behParams) -// Convert a u8 bparam to oBehParams -#define BPARAM_TO_OBEHPARAMS(val, shift) (((val) & BPARAM_MASK) << (BPARAM_SIZE * (shift))) +// Set a bparam in oBehParams without overwriting other bparams +#define SET_BPARAM(behParams, val, index, num) (behParams) = (CLEARED_BPARAM((behParams), (index), (num)) | SHIFTED_BPARAM((val), (index), (num))) +#define SET_BPARAM1(behParams, val) SET_BPARAM((behParams), (val), 1, 1) +#define SET_BPARAM2(behParams, val) SET_BPARAM((behParams), (val), 2, 1) +#define SET_BPARAM3(behParams, val) SET_BPARAM((behParams), (val), 3, 1) +#define SET_BPARAM4(behParams, val) SET_BPARAM((behParams), (val), 4, 1) + +// Set a bparam in oBehParams, clearing other bparams +#define SET_FULL_BPARAM(behParams, val, index, num) (behParams) = SHIFTED_BPARAM((val), (index), (num))) +#define SET_FULL_BPARAM1(behParams, val) SET_FULL_BPARAM((behParams), (val), 1, 1) +#define SET_FULL_BPARAM2(behParams, val) SET_FULL_BPARAM((behParams), (val), 2, 1) +#define SET_FULL_BPARAM3(behParams, val) SET_FULL_BPARAM((behParams), (val), 3, 1) +#define SET_FULL_BPARAM4(behParams, val) SET_FULL_BPARAM((behParams), (val), 4, 1) + +// OR a bparam into an index in oBehParams +#define OR_BPARAM(behParams, val, index, num) (behParams) |= SHIFTED_BPARAM((val), (index), (num)) +#define OR_BPARAM1(behParams, val) OR_BPARAM((behParams), (val), 1, 1) +#define OR_BPARAM2(behParams, val) OR_BPARAM((behParams), (val), 2, 1) +#define OR_BPARAM3(behParams, val) OR_BPARAM((behParams), (val), 3, 1) +#define OR_BPARAM4(behParams, val) OR_BPARAM((behParams), (val), 4, 1) + +// NAND a bparam into an index in oBehParams +#define NAND_BPARAM(behParams, val, index, num) (behParams) &= ~SHIFTED_BPARAM((val), (index), (num)) +#define NAND_BPARAM1(behParams, val) NAND_BPARAM((behParams), (val), 1, 1) +#define NAND_BPARAM2(behParams, val) NAND_BPARAM((behParams), (val), 2, 1) +#define NAND_BPARAM3(behParams, val) NAND_BPARAM((behParams), (val), 3, 1) +#define NAND_BPARAM4(behParams, val) NAND_BPARAM((behParams), (val), 4, 1) + +// Current object bparams +#define BPARAM1 GET_BPARAM1(o->oBehParams) +#define BPARAM2 GET_BPARAM2(o->oBehParams) +#define BPARAM3 GET_BPARAM3(o->oBehParams) +#define BPARAM4 GET_BPARAM4(o->oBehParams) -// Set oBehParams -#define SET_BPARAM1(p, val) (p) = BPARAM_TO_OBEHPARAMS((val), 3) -#define SET_BPARAM2(p, val) (p) = BPARAM_TO_OBEHPARAMS((val), 2) -#define SET_BPARAM3(p, val) (p) = BPARAM_TO_OBEHPARAMS((val), 1) -#define SET_BPARAM4(p, val) (p) = BPARAM_TO_OBEHPARAMS((val), 0) -// OR oBehParams -#define OR_BPARAM1(p, val) (p) |= BPARAM_TO_OBEHPARAMS((val), 3) -#define OR_BPARAM2(p, val) (p) |= BPARAM_TO_OBEHPARAMS((val), 2) -#define OR_BPARAM3(p, val) (p) |= BPARAM_TO_OBEHPARAMS((val), 1) -#define OR_BPARAM4(p, val) (p) |= BPARAM_TO_OBEHPARAMS((val), 0) /* oBehParams2ndByte */ enum ObjGeneralBehParams { @@ -1402,19 +1445,21 @@ enum BehParam1StarAct { // BPARAM1 /* Goomba triplet spawner */ /* oBehParams2ndByte */ - #define GOOMBA_TRIPLET_SPAWNER_BP_SIZE_MASK 0x00000003 - #define GOOMBA_TRIPLET_SPAWNER_BP_EXTRA_GOOMBAS_MASK 0x000000FC + #define GOOMBA_TRIPLET_SPAWNER_BP_SIZE_MASK 0x03 + #define GOOMBA_TRIPLET_SPAWNER_BP_EXTRA_GOOMBAS_MASK 0xFC /* oAction */ #define GOOMBA_TRIPLET_SPAWNER_ACT_UNLOADED 0x0 #define GOOMBA_TRIPLET_SPAWNER_ACT_LOADED 0x1 /* Goomba */ /* oBehParams2ndByte */ - #define GOOMBA_SIZE_REGULAR 0x0 - #define GOOMBA_SIZE_HUGE 0x1 - #define GOOMBA_SIZE_TINY 0x2 - #define GOOMBA_BP_SIZE_MASK 0x3 - #define GOOMBA_BP_TRIPLET_FLAG_MASK 0x000000FC + #define GOOMBA_SIZE_REGULAR 0x00 + #define GOOMBA_SIZE_HUGE 0x01 + #define GOOMBA_SIZE_TINY 0x02 + #define GOOMBA_BP_SIZE_MASK 0x03 + #define GOOMBA_BP_TRIPLET_FLAG_MASK 0xFC + /* BPARAM3 */ + #define GOOMBA_BP3_IS_FLOOMBA (1 << 7) /* oAction */ #define GOOMBA_ACT_WALK 0x0 #define GOOMBA_ACT_ATTACKED_MARIO 0x1 diff --git a/include/types.h b/include/types.h index 4b1474382..ec00607d3 100644 --- a/include/types.h +++ b/include/types.h @@ -10,8 +10,9 @@ #define BIT(i) (1 << (i)) #define BITMASK(size) ((BIT(size)) - 1) +#define SHIFTED_BITMASK(size, shift) (BITMASK(size) << shift) + #define COND_BIT(cond, dst, flag) { (dst) &= ~(flag); if (cond) (dst) |= (flag); } -#define FORCE_CRASH { *(vs8*)0 = 0; } #define SCREEN_CENTER_X (SCREEN_WIDTH / 2) #define SCREEN_CENTER_Y (SCREEN_HEIGHT / 2) diff --git a/src/game/interaction.c b/src/game/interaction.c index 77c4c179e..7c62fbe3d 100644 --- a/src/game/interaction.c +++ b/src/game/interaction.c @@ -777,12 +777,11 @@ u32 interact_star_or_key(struct MarioState *m, UNUSED u32 interactType, struct O #ifdef GLOBAL_STAR_IDS u32 starIndex = GET_BPARAM1(obj->oBehParams); #else - u32 starIndex = ((obj->oBehParams >> 24) & 0x1F); + u32 starIndex = (GET_BPARAM1(obj->oBehParams) & 0x1F); #endif save_file_collect_star_or_key(m->numCoins, starIndex); - m->numStars = - save_file_get_total_star_count((gCurrSaveFileNum - 1), (COURSE_MIN - 1), (COURSE_MAX - 1)); + m->numStars = save_file_get_total_star_count((gCurrSaveFileNum - 1), COURSE_NUM_TO_INDEX(COURSE_MIN), COURSE_NUM_TO_INDEX(COURSE_MAX)); if (!noExit) { drop_queued_background_music(); @@ -869,7 +868,7 @@ u32 interact_warp_door(struct MarioState *m, UNUSED u32 interactType, struct Obj u32 doorAction = ACT_UNINITIALIZED; #ifndef UNLOCK_ALL u32 saveFlags = save_file_get_flags(); - s16 warpDoorId = (obj->oBehParams >> 24); + s16 warpDoorId = GET_BPARAM1(obj->oBehParams); #endif if (m->action == ACT_WALKING || m->action == ACT_DECELERATING) { @@ -926,7 +925,7 @@ u32 interact_warp_door(struct MarioState *m, UNUSED u32 interactType, struct Obj u32 get_door_save_file_flag(struct Object *door) { u32 saveFileFlag = 0; - s16 requiredNumStars = (door->oBehParams >> 24); + s16 requiredNumStars = GET_BPARAM1(door->oBehParams); switch (requiredNumStars) { case 1: saveFileFlag = ((door->oPosY > 500.0f) ? SAVE_FLAG_UNLOCKED_PSS_DOOR : SAVE_FLAG_UNLOCKED_WF_DOOR ); break; @@ -940,9 +939,9 @@ u32 get_door_save_file_flag(struct Object *door) { } u32 interact_door(struct MarioState *m, UNUSED u32 interactType, struct Object *obj) { - s16 requiredNumStars = (obj->oBehParams >> 24); + s16 requiredNumStars = GET_BPARAM1(obj->oBehParams); #ifndef UNLOCK_ALL - s16 numStars = save_file_get_total_star_count(gCurrSaveFileNum - 1, COURSE_MIN - 1, COURSE_MAX - 1); + s16 numStars = save_file_get_total_star_count((gCurrSaveFileNum - 1), COURSE_NUM_TO_INDEX(COURSE_MIN), COURSE_NUM_TO_INDEX(COURSE_MAX)); #endif if (m->action == ACT_WALKING || m->action == ACT_DECELERATING) { #ifndef UNLOCK_ALL diff --git a/src/game/interaction.h b/src/game/interaction.h index 355ba4bcd..c34958055 100644 --- a/src/game/interaction.h +++ b/src/game/interaction.h @@ -72,8 +72,7 @@ // INTERACT_CLAM_OR_BUBBA #define INT_SUBTYPE_EATS_MARIO /* 0x00002000 */ (1 << 13) -enum AttackType -{ +enum AttackType { ATTACK_NONE, ATTACK_PUNCH, ATTACK_KICK_OR_TRIP, diff --git a/src/game/macro_special_objects.c b/src/game/macro_special_objects.c index fc2747819..bb4d3a9ab 100644 --- a/src/game/macro_special_objects.c +++ b/src/game/macro_special_objects.c @@ -100,15 +100,15 @@ void spawn_macro_objects(s32 areaIndex, MacroObject *macroObjList) { gMacroObjectDefaultParent.header.gfx.activeAreaIndex = areaIndex; while (TRUE) { if (*macroObjList == -1) break; // An encountered value of -1 means the list has ended. - presetID = (*macroObjList & 0x1FF) - 31; // Preset identifier for MacroObjectPresets array + presetID = ((*macroObjList & 0x1FF) - 31); // Preset identifier for MacroObjectPresets array if (presetID < 0) break; // Set macro object properties from the list - macroObject[MACRO_OBJ_Y_ROT ] = ((*macroObjList++ >> 9) & 0x7F) << 1; // Y-Rotation - macroObject[MACRO_OBJ_X ] = *macroObjList++; // X position - macroObject[MACRO_OBJ_Y ] = *macroObjList++; // Y position - macroObject[MACRO_OBJ_Z ] = *macroObjList++; // Z position - macroObject[MACRO_OBJ_PARAMS] = *macroObjList++; // Behavior params + macroObject[MACRO_OBJ_Y_ROT ] = (((*macroObjList++ >> 9) & 0x7F) << 1); // Y-Rotation + macroObject[MACRO_OBJ_X ] = *macroObjList++; // X position + macroObject[MACRO_OBJ_Y ] = *macroObjList++; // Y position + macroObject[MACRO_OBJ_Z ] = *macroObjList++; // Z position + macroObject[MACRO_OBJ_PARAMS] = *macroObjList++; // Behavior params // Get the preset values from the MacroObjectPresets list. preset.model = MacroObjectPresets[presetID].model; @@ -117,7 +117,7 @@ void spawn_macro_objects(s32 areaIndex, MacroObject *macroObjList) { if (preset.param != 0) { macroObject[MACRO_OBJ_PARAMS] = - (macroObject[MACRO_OBJ_PARAMS] & 0xFF00) + (preset.param & 0x00FF); + (macroObject[MACRO_OBJ_PARAMS] & 0xFF00) | (preset.param & 0x00FF); } // If object has been killed, prevent it from respawning @@ -137,12 +137,12 @@ void spawn_macro_objects(s32 areaIndex, MacroObject *macroObjList) { ); newObj->oUnusedCoinParams = macroObject[MACRO_OBJ_PARAMS]; - newObj->oBehParams = (((macroObject[MACRO_OBJ_PARAMS] & 0x00FF) << 16) - + (macroObject[MACRO_OBJ_PARAMS] & 0xFF00)); + newObj->oBehParams = (((macroObject[MACRO_OBJ_PARAMS] & 0x00FF) << 16) + | (macroObject[MACRO_OBJ_PARAMS] & 0xFF00)); newObj->oBehParams2ndByte = (macroObject[MACRO_OBJ_PARAMS] & 0x00FF); newObj->respawnInfoType = RESPAWN_INFO_TYPE_MACRO_OBJECT; newObj->respawnInfo = (macroObjList - 1); - newObj->parentObj = newObj; + newObj->parentObj = newObj; } } } diff --git a/src/game/mario_actions_cutscene.c b/src/game/mario_actions_cutscene.c index 7898d6dd3..bfde9fde4 100644 --- a/src/game/mario_actions_cutscene.c +++ b/src/game/mario_actions_cutscene.c @@ -756,7 +756,7 @@ s32 act_unlocking_key_door(struct MarioState *m) { stop_and_set_height_to_floor(m); if (is_anim_at_end(m)) { - if ((m->usedObj->oBehParams >> 24) == 1) { + if (GET_BPARAM1(m->usedObj->oBehParams) == 0x1) { save_file_set_flags(SAVE_FLAG_UNLOCKED_UPSTAIRS_DOOR); save_file_clear_flags(SAVE_FLAG_HAVE_KEY_2); } else {