Fixed screenblock overflow bug and once again merged up/down versions of POP_MENU_ANIM_RECT

This commit is contained in:
MeirGavish
2025-07-20 01:55:49 +03:00
parent ab8200b2a3
commit 708d9a813f
2 changed files with 37 additions and 32 deletions
+9 -10
View File
@@ -124,10 +124,7 @@ static inline Card *discard_pop()
// Screenblock rects // Screenblock rects
static const Rect ROUND_END_MENU_RECT = {9, 7, 24, 20 }; static const Rect ROUND_END_MENU_RECT = {9, 7, 24, 20 };
// These need to be here because moving tiles down below 30 bleeds memory into the next screenblock I think static const Rect POP_MENU_ANIM_RECT = {9, 7, 24, 31 };
static const Rect POP_MENU_ANIM_RECT_DOWN = {9, 6, 24, 30 };
static const Rect POP_MENU_ANIM_RECT_UP = {9, 7, 24, 31 };
// The rect for popping menu animations (round end, shop, blinds) // The rect for popping menu animations (round end, shop, blinds)
// - extends beyond the visible screen to the end of the screenblock // - extends beyond the visible screen to the end of the screenblock
// It includes both the target and source position rects. // It includes both the target and source position rects.
@@ -1693,7 +1690,7 @@ void game_round_end()
} }
case 1: // This creates the top 16 by 7 tiles of the pop up. It places it in vram, moving it up one tile each frame, not clearing the previous row of tiles so they fill the blank space as it moves up. case 1: // This creates the top 16 by 7 tiles of the pop up. It places it in vram, moving it up one tile each frame, not clearing the previous row of tiles so they fill the blank space as it moves up.
{ {
main_bg_se_copy_rect_1_tile_vert(POP_MENU_ANIM_RECT_UP, SE_UP); main_bg_se_copy_rect_1_tile_vert(POP_MENU_ANIM_RECT, SE_UP);
if (timer == 13) if (timer == 13)
{ {
@@ -1963,7 +1960,7 @@ void game_shop()
{ {
case 0: // Intro sequence (menu and shop icon coming into frame) case 0: // Intro sequence (menu and shop icon coming into frame)
{ {
main_bg_se_copy_rect_1_tile_vert(POP_MENU_ANIM_RECT_UP, SE_UP); main_bg_se_copy_rect_1_tile_vert(POP_MENU_ANIM_RECT, SE_UP);
if (timer >= 7) // Shift the shop icon if (timer >= 7) // Shift the shop icon
{ {
@@ -2066,7 +2063,7 @@ void game_shop()
case 2: // Outro sequence (menu and shop icon going out of frame) case 2: // Outro sequence (menu and shop icon going out of frame)
{ {
// Shift the shop panel // Shift the shop panel
main_bg_se_move_rect_1_tile_vert(POP_MENU_ANIM_RECT_DOWN, SE_DOWN); main_bg_se_move_rect_1_tile_vert(POP_MENU_ANIM_RECT, SE_DOWN);
main_bg_se_copy_rect_1_tile_vert(TOP_LEFT_PANEL_ANIM_RECT, SE_UP); main_bg_se_copy_rect_1_tile_vert(TOP_LEFT_PANEL_ANIM_RECT, SE_UP);
@@ -2120,7 +2117,7 @@ void game_blind_select()
case 0: // Intro sequence (menu coming into frame) case 0: // Intro sequence (menu coming into frame)
{ {
change_background(BG_ID_BLIND_SELECT); change_background(BG_ID_BLIND_SELECT);
main_bg_se_copy_rect_1_tile_vert(POP_MENU_ANIM_RECT_UP, SE_UP); main_bg_se_copy_rect_1_tile_vert(POP_MENU_ANIM_RECT, SE_UP);
for (int i = 0; i < MAX_BLINDS; i++) for (int i = 0; i < MAX_BLINDS; i++)
{ {
@@ -2164,7 +2161,7 @@ void game_blind_select()
// TODO: Create a generic vertical move by any number of tiles to avoid for loops? // TODO: Create a generic vertical move by any number of tiles to avoid for loops?
for (int i = 0; i < 12; i++) for (int i = 0; i < 12; i++)
{ {
main_bg_se_copy_rect_1_tile_vert(POP_MENU_ANIM_RECT_UP, SE_UP); main_bg_se_copy_rect_1_tile_vert(POP_MENU_ANIM_RECT, SE_UP);
} }
for (int i = 0; i < MAX_BLINDS; i++) for (int i = 0; i < MAX_BLINDS; i++)
@@ -2193,7 +2190,9 @@ void game_blind_select()
{ {
if (timer < 15) if (timer < 15)
{ {
main_bg_se_move_rect_1_tile_vert(POP_MENU_ANIM_RECT_DOWN, SE_DOWN); Rect blinds_rect = POP_MENU_ANIM_RECT;
blinds_rect.top -= 1; // Because of the raised blind
main_bg_se_move_rect_1_tile_vert(blinds_rect, SE_DOWN);
for (int i = 0; i < MAX_BLINDS; i++) for (int i = 0; i < MAX_BLINDS; i++)
{ {
+27 -21
View File
@@ -4,7 +4,7 @@
#include "graphic_utils.h" #include "graphic_utils.h"
const Rect FULL_SCREENBLOCK_RECT = { 0, 0, SE_ROW_LEN, SE_COL_LEN }; const Rect FULL_SCREENBLOCK_RECT = { 0, 0, SE_ROW_LEN - 1, SE_COL_LEN - 1};
// Clips a rect of screenblock entries to a specified rect // Clips a rect of screenblock entries to a specified rect
// The bounding rect is not required to be within screenblock boundaries // The bounding rect is not required to be within screenblock boundaries
@@ -29,12 +29,19 @@ u16 main_bg_se_get_tile(BG_POINT pos)
} }
// Clips a rect of screenblock entries to be within one step of // Clips a rect of screenblock entries to be within one step of
// screenblock boundaries vertically (1 step from top, 1 step from bottom. // screenblock boundaries vertically depending on direction.
static void clip_se_rect_within_step_of_full_screen_vert(Rect* se_rect) static void clip_se_rect_within_step_of_full_screen_vert(Rect* se_rect, int direction)
{ {
Rect bounding_rect = FULL_SCREENBLOCK_RECT; Rect bounding_rect = FULL_SCREENBLOCK_RECT;
bounding_rect.top += 1; if (direction == SE_UP)
bounding_rect.bottom -= -1; {
bounding_rect.top += 1;
}
else if (direction == SE_DOWN)
{
bounding_rect.bottom -= 1;
}
clip_se_rect_to_bounding_rect(se_rect, &bounding_rect); clip_se_rect_to_bounding_rect(se_rect, &bounding_rect);
} }
@@ -51,7 +58,9 @@ void main_bg_se_clear_rect(Rect se_rect)
} }
} }
void main_bg_se_copy_rect_1_tile_vert(Rect se_rect, int direction)
// Internal static function to merge implementation of move/copy functions.
static void main_bg_se_copy_or_move_rect_1_tile_vert(Rect se_rect, int direction, bool move)
{ {
if (se_rect.left > se_rect.right if (se_rect.left > se_rect.right
|| (direction != SE_UP && direction != SE_DOWN)) || (direction != SE_UP && direction != SE_DOWN))
@@ -60,7 +69,7 @@ void main_bg_se_copy_rect_1_tile_vert(Rect se_rect, int direction)
} }
// Clip to avoid read/write overflow of the screenblock // Clip to avoid read/write overflow of the screenblock
clip_se_rect_within_step_of_full_screen_vert(&se_rect); clip_se_rect_within_step_of_full_screen_vert(&se_rect, direction);
int start = (direction == SE_UP) ? se_rect.top : se_rect.bottom; int start = (direction == SE_UP) ? se_rect.top : se_rect.bottom;
int end = (direction == SE_UP) ? se_rect.bottom : se_rect.top; int end = (direction == SE_UP) ? se_rect.bottom : se_rect.top;
@@ -71,24 +80,21 @@ void main_bg_se_copy_rect_1_tile_vert(Rect se_rect, int direction)
&se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * y], &se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * y],
rect_width(&se_rect)); rect_width(&se_rect));
} }
if (move)
{
memset16(&se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * (end)], 0x0000, rect_width(&se_rect));
}
}
void main_bg_se_copy_rect_1_tile_vert(Rect se_rect, int direction)
{
main_bg_se_copy_or_move_rect_1_tile_vert(se_rect, direction, false);
} }
void main_bg_se_move_rect_1_tile_vert(Rect se_rect, int direction) void main_bg_se_move_rect_1_tile_vert(Rect se_rect, int direction)
{ {
if (se_rect.left > se_rect.right main_bg_se_copy_or_move_rect_1_tile_vert(se_rect, direction, true);
|| (direction != SE_UP && direction != SE_DOWN))
{
return;
}
// Clip to avoid read/write overflow of the screenblock
clip_se_rect_within_step_of_full_screen_vert(&se_rect);
int deleted_y = (direction == SE_UP) ? se_rect.bottom : se_rect.top;
main_bg_se_copy_rect_1_tile_vert(se_rect, direction);
memset16(&se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * (deleted_y)], 0x0000, rect_width(&se_rect));
} }
void main_bg_se_copy_rect(Rect se_rect, BG_POINT pos) void main_bg_se_copy_rect(Rect se_rect, BG_POINT pos)