From 9c77aa3c66ca558ea99600a04f60ff35f0776f14 Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Sun, 17 Sep 2023 15:37:33 -0400 Subject: [PATCH 1/2] Improved support for 64x64 followers. Updated reflection code. Added 24x24 subsprite tables. --- include/global.h | 2 + .../object_events/object_event_subsprites.h | 2268 +++++++++++------ src/event_object_movement.c | 70 +- src/field_effect_helpers.c | 168 +- 4 files changed, 1621 insertions(+), 887 deletions(-) diff --git a/include/global.h b/include/global.h index 26c86cf2f1..e4cb2e1103 100644 --- a/include/global.h +++ b/include/global.h @@ -85,6 +85,8 @@ #define SAFE_DIV(a, b) ((a) / (b)) #endif +#define IS_POW_OF_TWO(n) (((n) & ((n)-1)) == 0) + // 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 diff --git a/src/data/object_events/object_event_subsprites.h b/src/data/object_events/object_event_subsprites.h index 7a3c90dc4d..cb17e219e0 100755 --- a/src/data/object_events/object_event_subsprites.h +++ b/src/data/object_events/object_event_subsprites.h @@ -1,3 +1,6 @@ +#define SUBSPRITE_TABLE_ENTRY(x) {ARRAY_COUNT(x), x} +#define SUBSPRITE_SHAPE(w, h) .shape = SPRITE_SHAPE(w##x##h), .size = SPRITE_SIZE(w##x##h) + static const struct Subsprite sOamTable_16x16_0[] = { { .x = -8, @@ -278,516 +281,11 @@ static const struct SubspriteTable sOamTables_32x32[] = { {ARRAY_COUNT(sOamTable_32x32_4), sOamTable_32x32_4} }; -static const struct Subsprite sOamTable_48x48[] = { - { - .x = -24, - .y = -24, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 0, - .priority = 1 - }, - { - .x = 8, - .y = -24, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 4, - .priority = 1 - }, - { - .x = -24, - .y = -16, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 6, - .priority = 1 - }, - { - .x = 8, - .y = -16, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 10, - .priority = 1 - }, - { - .x = -24, - .y = -8, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 12, - .priority = 2 - }, - { - .x = 8, - .y = -8, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 16, - .priority = 2 - }, - { - .x = -24, - .y = 0, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 18, - .priority = 2 - }, - { - .x = 8, - .y = 0, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 22, - .priority = 2 - }, - { - .x = -24, - .y = 8, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 24, - .priority = 2 - }, - { - .x = 8, - .y = 8, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 28, - .priority = 2 - }, - { - .x = -24, - .y = 16, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 30, - .priority = 2 - }, - { - .x = 8, - .y = 16, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 34, - .priority = 2 - } -}; - -static const struct Subsprite sOamTable_48x48_4[] = { - { - .x = -24, - .y = -24, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 0, - .priority = 1 - }, - { - .x = 8, - .y = -24, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 4, - .priority = 1 - }, - { - .x = -24, - .y = -16, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 6, - .priority = 1 - }, - { - .x = 8, - .y = -16, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 10, - .priority = 1 - }, - { - .x = -24, - .y = -8, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 12, - .priority = 1 - }, - { - .x = 8, - .y = -8, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 16, - .priority = 1 - }, - { - .x = -24, - .y = 0, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 18, - .priority = 1 - }, - { - .x = 8, - .y = 0, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 22, - .priority = 1 - }, - { - .x = -24, - .y = 8, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 24, - .priority = 1 - }, - { - .x = 8, - .y = 8, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 28, - .priority = 1 - }, - { - .x = -24, - .y = 16, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 30, - .priority = 1 - }, - { - .x = 8, - .y = 16, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 34, - .priority = 1 - } -}; - -static const struct Subsprite sOamTable_48x48_HotSprings[] = { - { - .x = -24, - .y = -24, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 0, - .priority = 2 - }, - { - .x = 8, - .y = -24, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 4, - .priority = 2 - }, - { - .x = -24, - .y = -16, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 6, - .priority = 2 - }, - { - .x = 8, - .y = -16, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 10, - .priority = 2 - }, - { - .x = -24, - .y = -8, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 12, - .priority = 2 - }, - { - .x = 8, - .y = -8, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 16, - .priority = 2 - }, - { - .x = -24, - .y = 0, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 18, - .priority = 2 - }, - { - .x = 8, - .y = 0, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 22, - .priority = 2 - }, - { - .x = -24, - .y = 8, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 24, - .priority = 2 - }, - { - .x = 8, - .y = 8, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 28, - .priority = 2 - }, - { - .x = -24, - .y = 16, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 30, - .priority = 3 - }, - { - .x = 8, - .y = 16, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 34, - .priority = 3 - } -}; - -static const struct Subsprite sOamTable_48x48_Grass2[] = { - { - .x = -24, - .y = -24, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 0, - .priority = 2 - }, - { - .x = 8, - .y = -24, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 4, - .priority = 2 - }, - { - .x = -24, - .y = -16, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 6, - .priority = 2 - }, - { - .x = 8, - .y = -16, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 10, - .priority = 2 - }, - { - .x = -24, - .y = -8, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 12, - .priority = 2 - }, - { - .x = 8, - .y = -8, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 16, - .priority = 2 - }, - { - .x = -24, - .y = 0, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 18, - .priority = 2 - }, - { - .x = 8, - .y = 0, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 22, - .priority = 2 - }, - { - .x = -24, - .y = 8, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 24, - .priority = 3 - }, - { - .x = 8, - .y = 8, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 28, - .priority = 3 - }, - { - .x = -24, - .y = 16, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 30, - .priority = 3 - }, - { - .x = 8, - .y = 16, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 34, - .priority = 3 - } -}; - -static const struct Subsprite sOamTable_48x48_Grass1[] = { - { - .x = -24, - .y = -24, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 0, - .priority = 1 - }, - { - .x = 8, - .y = -24, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 4, - .priority = 1 - }, - { - .x = -24, - .y = -16, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 6, - .priority = 1 - }, - { - .x = 8, - .y = -16, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 10, - .priority = 1 - }, - { - .x = -24, - .y = -8, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 12, - .priority = 1 - }, - { - .x = 8, - .y = -8, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 16, - .priority = 1 - }, - { - .x = -24, - .y = 0, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 18, - .priority = 1 - }, - { - .x = 8, - .y = 0, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 22, - .priority = 1 - }, - { - .x = -24, - .y = 8, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 24, - .priority = 3 - }, - { - .x = 8, - .y = 8, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 28, - .priority = 3 - }, - { - .x = -24, - .y = 16, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 30, - .priority = 3 - }, - { - .x = 8, - .y = 16, - .shape = SPRITE_SHAPE(16x8), - .size = SPRITE_SIZE(16x8), - .tileOffset = 34, - .priority = 3 - } -}; - -static const struct SubspriteTable sOamTables_48x48[] = { - {ARRAY_COUNT(sOamTable_48x48), sOamTable_48x48}, - {ARRAY_COUNT(sOamTable_48x48), sOamTable_48x48}, // elevation 3 - {ARRAY_COUNT(sOamTable_48x48_4), sOamTable_48x48_4}, // elevation 4 - {ARRAY_COUNT(sOamTable_48x48_HotSprings), sOamTable_48x48_HotSprings}, // hot springs - {ARRAY_COUNT(sOamTable_48x48_Grass2), sOamTable_48x48_Grass2}, // long grass - {ARRAY_COUNT(sOamTable_48x48_Grass1), sOamTable_48x48_Grass1} // long grass priority 1 -}; - static const struct Subsprite sOamTable_64x32_0[] = { { .x = -32, .y = -16, - .shape = SPRITE_SHAPE(64x32), - .size = SPRITE_SIZE(64x32), + SUBSPRITE_SHAPE(64, 32), .tileOffset = 0, .priority = 2 } @@ -797,8 +295,7 @@ static const struct Subsprite sOamTable_64x32_1[] = { { .x = -32, .y = -16, - .shape = SPRITE_SHAPE(64x32), - .size = SPRITE_SIZE(64x32), + SUBSPRITE_SHAPE(64, 32), .tileOffset = 0, .priority = 1 } @@ -808,8 +305,7 @@ static const struct Subsprite sOamTable_64x32_2[] = { { .x = -32, .y = -16, - .shape = SPRITE_SHAPE(64x32), - .size = SPRITE_SIZE(64x32), + SUBSPRITE_SHAPE(64, 32), .tileOffset = 0, .priority = 2 } @@ -819,8 +315,7 @@ static const struct Subsprite sOamTable_64x32_3[] = { { .x = -32, .y = -16, - .shape = SPRITE_SHAPE(64x32), - .size = SPRITE_SIZE(64x32), + SUBSPRITE_SHAPE(64, 32), .tileOffset = 0, .priority = 2 } @@ -840,8 +335,7 @@ static const struct Subsprite sOamTable_64x64_0[] = { { .x = -32, .y = -32, - .shape = SPRITE_SHAPE(64x64), - .size = SPRITE_SIZE(64x64), + SUBSPRITE_SHAPE(64, 64), .tileOffset = 0, .priority = 2 } @@ -851,8 +345,7 @@ static const struct Subsprite sOamTable_64x64_1[] = { { .x = -32, .y = -32, - .shape = SPRITE_SHAPE(64x64), - .size = SPRITE_SIZE(64x64), + SUBSPRITE_SHAPE(64, 64), .tileOffset = 0, .priority = 1 } @@ -862,8 +355,7 @@ static const struct Subsprite sOamTable_64x64_2[] = { { .x = -32, .y = -32, - .shape = SPRITE_SHAPE(64x64), - .size = SPRITE_SIZE(64x64), + SUBSPRITE_SHAPE(64, 64), .tileOffset = 0, .priority = 2 } @@ -873,8 +365,7 @@ static const struct Subsprite sOamTable_64x64_3[] = { { .x = -32, .y = -32, - .shape = SPRITE_SHAPE(64x64), - .size = SPRITE_SIZE(64x64), + SUBSPRITE_SHAPE(64, 64), .tileOffset = 0, .priority = 2 } @@ -889,263 +380,6 @@ static const struct SubspriteTable sOamTables_64x64[] = { {ARRAY_COUNT(sOamTable_64x64_3), sOamTable_64x64_3} }; -static const struct Subsprite sOamTable_64x64_Follower[] = { - { - .x = -32, - .y = -32, - .shape = SPRITE_SHAPE(64x32), - .size = SPRITE_SIZE(64x32), - .tileOffset = 0, - .priority = 1 - }, - { - .x = -32, - .y = 0, - .shape = SPRITE_SHAPE(64x32), - .size = SPRITE_SIZE(64x32), - .tileOffset = 32, - .priority = 2 - } -}; - -static const struct Subsprite sOamTable_64x64_HotSprings[] = { - { - .x = -32, - .y = -32, - .shape = SPRITE_SHAPE(64x32), - .size = SPRITE_SIZE(64x32), - .tileOffset = 0, - .priority = 2 - }, - { - .x = -32, - .y = 0, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 32, - .priority = 2 - }, - { - .x = 0, - .y = 0, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 36, - .priority = 2 - }, - { - .x = -32, - .y = 8, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 40, - .priority = 2 - }, - { - .x = 0, - .y = 8, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 44, - .priority = 2 - }, - { - .x = -32, - .y = 16, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 48, - .priority = 2 - }, - { - .x = 0, - .y = 16, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 52, - .priority = 2 - }, - { - .x = -32, - .y = 24, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 56, - .priority = 3 - }, - { - .x = 0, - .y = 24, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 60, - .priority = 3 - }, -}; - -static const struct Subsprite sOamTable_64x64_Grass2[] = { - { - .x = -32, - .y = -32, - .shape = SPRITE_SHAPE(64x32), - .size = SPRITE_SIZE(64x32), - .tileOffset = 0, - .priority = 2 - }, - { - .x = -32, - .y = 0, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 32, - .priority = 2 - }, - { - .x = 0, - .y = 0, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 36, - .priority = 2 - }, - { - .x = -32, - .y = 8, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 40, - .priority = 2 - }, - { - .x = 0, - .y = 8, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 44, - .priority = 2 - }, - { - .x = -32, - .y = 16, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 48, - .priority = 3 - }, - { - .x = 0, - .y = 16, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 52, - .priority = 3 - }, - { - .x = -32, - .y = 24, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 56, - .priority = 3 - }, - { - .x = 0, - .y = 24, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 60, - .priority = 3 - }, -}; - -static const struct Subsprite sOamTable_64x64_Grass1[] = { - { - .x = -32, - .y = -32, - .shape = SPRITE_SHAPE(64x32), - .size = SPRITE_SIZE(64x32), - .tileOffset = 0, - .priority = 1 - }, - { - .x = -32, - .y = 0, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 32, - .priority = 1 - }, - { - .x = 0, - .y = 0, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 36, - .priority = 1 - }, - { - .x = -32, - .y = 8, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 40, - .priority = 1 - }, - { - .x = 0, - .y = 8, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 44, - .priority = 1 - }, - { - .x = -32, - .y = 16, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 48, - .priority = 3 - }, - { - .x = 0, - .y = 16, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 52, - .priority = 3 - }, - { - .x = -32, - .y = 24, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 56, - .priority = 3 - }, - { - .x = 0, - .y = 24, - .shape = SPRITE_SHAPE(32x8), - .size = SPRITE_SIZE(32x8), - .tileOffset = 60, - .priority = 3 - }, -}; - -// For following pokemon -// Makes the top 32 pixels priority 1, -// so that very tall pokemon's heads -// will appear on top of buildings, etc. -static const struct SubspriteTable sOamTables_64x64_Follower[] = { - {}, // unused - {ARRAY_COUNT(sOamTable_64x64_Follower), sOamTable_64x64_Follower}, // elevation 3 - {ARRAY_COUNT(sOamTable_64x64_1), sOamTable_64x64_1}, // elevation 4 - {ARRAY_COUNT(sOamTable_64x64_HotSprings), sOamTable_64x64_HotSprings}, // hot springs - {ARRAY_COUNT(sOamTable_64x64_Grass2), sOamTable_64x64_Grass2}, // long grass - {ARRAY_COUNT(sOamTable_64x64_Grass1), sOamTable_64x64_Grass1} // long grass priority 1 -}; - static const struct Subsprite sOamTable_96x40_0[] = { { .x = -48, @@ -2181,3 +1415,1483 @@ static const struct SubspriteTable sOamTables_88x32[] = { {ARRAY_COUNT(sOamTable_88x32_3), sOamTable_88x32_3}, {ARRAY_COUNT(sOamTable_88x32_3), sOamTable_88x32_3} }; + +#if LARGE_OW_SUPPORT +// These tables allow (virtual) sprite sizes so that +// some space can be saved by making graphics smaller. +// Note: When using these for followers, the minimum +// `size` you must set in GraphicsInfo is 512. + +static const struct Subsprite sOamTable_16x24_0[] = { + { + .x = -8, .y = -12, + SUBSPRITE_SHAPE(16, 16), + .tileOffset = 0, + .priority = 2 + }, + { + .x = -8, .y = 4, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 4, + .priority = 2 + }, +}; + +static const struct Subsprite sOamTable_16x24_1[] = { + { + .x = -8, .y = -12, + SUBSPRITE_SHAPE(16, 16), + .tileOffset = 0, + .priority = 1 + }, + { + .x = -8, .y = 4, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 4, + .priority = 1 + }, +}; + +static const struct Subsprite sOamTable_16x24_2[] = { + { + .x = -8, .y = -12, + SUBSPRITE_SHAPE(16, 16), + .tileOffset = 0, + .priority = 2 + }, + { + .x = -8, .y = 4, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 4, + .priority = 3 + }, +}; + +static const struct Subsprite sOamTable_16x24_3[] = { + { + .x = -8, .y = -12, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 0, + .priority = 2 + }, + { + .x = -8, .y = -4, + SUBSPRITE_SHAPE(16, 16), + .tileOffset = 2, + .priority = 3 + }, +}; + +static const struct Subsprite sOamTable_16x24_4[] = { + { + .x = -8, .y = -12, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 0, + .priority = 1 + }, + { + .x = -8, .y = -4, + SUBSPRITE_SHAPE(16, 16), + .tileOffset = 2, + .priority = 3 + }, +}; + +static const struct Subsprite sOamTable_32x24_0[] = { + { + .x = -16, .y = -12, + SUBSPRITE_SHAPE(32, 16), + .tileOffset = 0, + .priority = 2 + }, + { + .x = -16, .y = 4, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 8, + .priority = 2 + }, +}; + +static const struct Subsprite sOamTable_32x24_1[] = { + { + .x = -16, .y = -12, + SUBSPRITE_SHAPE(32, 16), + .tileOffset = 0, + .priority = 1 + }, + { + .x = -16, .y = 4, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 8, + .priority = 1 + }, +}; + +static const struct Subsprite sOamTable_32x24_2[] = { + { + .x = -16, .y = -12, + SUBSPRITE_SHAPE(32, 16), + .tileOffset = 0, + .priority = 2 + }, + { + .x = -16, .y = 4, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 8, + .priority = 3 + }, +}; + +static const struct Subsprite sOamTable_32x24_3[] = { + { + .x = -16, .y = -12, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 0, + .priority = 2 + }, + { + .x = -16, .y = -4, + SUBSPRITE_SHAPE(32, 16), + .tileOffset = 4, + .priority = 3 + }, +}; + +static const struct Subsprite sOamTable_32x24_4[] = { + { + .x = -16, .y = -12, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 0, + .priority = 1 + }, + { + .x = -16, .y = -4, + SUBSPRITE_SHAPE(32, 16), + .tileOffset = 4, + .priority = 3 + }, +}; + +static const struct Subsprite sOamTable_24x16_0[] = { + { + .x = -12, .y = -8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 0, + .priority = 2 + }, + { + .x = 4, .y = -8, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 2, + .priority = 2 + }, + { + .x = -12, .y = 0, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 3, + .priority = 2 + }, + { + .x = 4, .y = 0, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 5, + .priority = 2 + }, +}; + +static const struct Subsprite sOamTable_24x16_1[] = { + { + .x = -12, .y = -8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 0, + .priority = 1 + }, + { + .x = 4, .y = -8, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 2, + .priority = 1 + }, + { + .x = -12, .y = 0, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 3, + .priority = 1 + }, + { + .x = 4, .y = 0, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 5, + .priority = 1 + }, +}; + +static const struct Subsprite sOamTable_24x16_2[] = { + { + .x = -12, .y = -8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 0, + .priority = 2 + }, + { + .x = 4, .y = -8, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 2, + .priority = 2 + }, + { + .x = -12, .y = 0, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 3, + .priority = 3 + }, + { + .x = 4, .y = 0, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 5, + .priority = 3 + }, +}; + +static const struct Subsprite sOamTable_24x16_3[] = { + { + .x = -12, .y = -8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 0, + .priority = 3 + }, + { + .x = 4, .y = -8, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 2, + .priority = 3 + }, + { + .x = -12, .y = 0, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 3, + .priority = 3 + }, + { + .x = 4, .y = 0, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 5, + .priority = 3 + }, +}; + +static const struct Subsprite sOamTable_24x24_0[] = { + { + .x = -12, .y = -12, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 0, + .priority = 2 + }, + { + .x = 4, .y = -12, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 2, + .priority = 2 + }, + { + .x = -12, .y = -4, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 3, + .priority = 2 + }, + { + .x = 4, .y = -4, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 5, + .priority = 2 + }, + { + .x = -12, .y = 4, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 6, + .priority = 2 + }, + { + .x = 4, .y = 4, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 8, + .priority = 2 + }, +}; + +static const struct Subsprite sOamTable_24x24_1[] = { + { + .x = -12, .y = -12, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 0, + .priority = 1 + }, + { + .x = 4, .y = -12, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 2, + .priority = 1 + }, + { + .x = -12, .y = -4, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 3, + .priority = 1 + }, + { + .x = 4, .y = -4, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 5, + .priority = 1 + }, + { + .x = -12, .y = 4, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 6, + .priority = 1 + }, + { + .x = 4, .y = 4, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 8, + .priority = 1 + }, +}; + +static const struct Subsprite sOamTable_24x24_2[] = { + { + .x = -12, .y = -12, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 0, + .priority = 2 + }, + { + .x = 4, .y = -12, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 2, + .priority = 2 + }, + { + .x = -12, .y = -4, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 3, + .priority = 2 + }, + { + .x = 4, .y = -4, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 5, + .priority = 2 + }, + { + .x = -12, .y = 4, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 6, + .priority = 3 + }, + { + .x = 4, .y = 4, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 8, + .priority = 3 + }, +}; + +static const struct Subsprite sOamTable_24x24_3[] = { + { + .x = -12, .y = -12, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 0, + .priority = 2 + }, + { + .x = 4, .y = -12, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 2, + .priority = 2 + }, + { + .x = -12, .y = -4, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 3, + .priority = 3 + }, + { + .x = 4, .y = -4, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 5, + .priority = 3 + }, + { + .x = -12, .y = 4, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 6, + .priority = 3 + }, + { + .x = 4, .y = 4, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 8, + .priority = 3 + }, +}; + +static const struct Subsprite sOamTable_24x24_4[] = { + { + .x = -12, .y = -12, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 0, + .priority = 1 + }, + { + .x = 4, .y = -12, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 2, + .priority = 1 + }, + { + .x = -12, .y = -4, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 3, + .priority = 3 + }, + { + .x = 4, .y = -4, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 5, + .priority = 3 + }, + { + .x = -12, .y = 4, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 6, + .priority = 3 + }, + { + .x = 4, .y = 4, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 8, + .priority = 3 + }, +}; + +static const struct Subsprite sOamTable_24x32_0[] = { + { + .x = -12, .y = -16, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 0, + .priority = 2 + }, + { + .x = 4, .y = -16, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 2, + .priority = 2 + }, + { + .x = -12, .y = -8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 3, + .priority = 2 + }, + { + .x = 4, .y = -8, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 5, + .priority = 2 + }, + { + .x = -12, .y = 0, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 6, + .priority = 2 + }, + { + .x = 4, .y = 0, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 8, + .priority = 2 + }, + { + .x = -12, .y = 8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 9, + .priority = 2 + }, + { + .x = 4, .y = 8, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 11, + .priority = 2 + }, +}; + +static const struct Subsprite sOamTable_24x32_1[] = { + { + .x = -12, .y = -16, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 0, + .priority = 1 + }, + { + .x = 4, .y = -16, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 2, + .priority = 1 + }, + { + .x = -12, .y = -8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 3, + .priority = 1 + }, + { + .x = 4, .y = -8, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 5, + .priority = 1 + }, + { + .x = -12, .y = 0, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 6, + .priority = 1 + }, + { + .x = 4, .y = 0, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 8, + .priority = 1 + }, + { + .x = -12, .y = 8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 9, + .priority = 1 + }, + { + .x = 4, .y = 8, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 11, + .priority = 1 + }, +}; + +static const struct Subsprite sOamTable_24x32_2[] = { + { + .x = -12, .y = -16, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 0, + .priority = 2 + }, + { + .x = 4, .y = -16, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 2, + .priority = 2 + }, + { + .x = -12, .y = -8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 3, + .priority = 2 + }, + { + .x = 4, .y = -8, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 5, + .priority = 2 + }, + { + .x = -12, .y = 0, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 6, + .priority = 2 + }, + { + .x = 4, .y = 0, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 8, + .priority = 2 + }, + { + .x = -12, .y = 8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 9, + .priority = 3 + }, + { + .x = 4, .y = 8, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 11, + .priority = 3 + }, +}; + +static const struct Subsprite sOamTable_24x32_3[] = { + { + .x = -12, .y = -16, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 0, + .priority = 2 + }, + { + .x = 4, .y = -16, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 2, + .priority = 2 + }, + { + .x = -12, .y = -8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 3, + .priority = 2 + }, + { + .x = 4, .y = -8, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 5, + .priority = 2 + }, + { + .x = -12, .y = 0, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 6, + .priority = 3 + }, + { + .x = 4, .y = 0, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 8, + .priority = 3 + }, + { + .x = -12, .y = 8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 9, + .priority = 3 + }, + { + .x = 4, .y = 8, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 11, + .priority = 3 + }, +}; + +static const struct Subsprite sOamTable_24x32_4[] = { + { + .x = -12, .y = -16, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 0, + .priority = 1 + }, + { + .x = 4, .y = -16, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 2, + .priority = 1 + }, + { + .x = -12, .y = -8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 3, + .priority = 1 + }, + { + .x = 4, .y = -8, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 5, + .priority = 1 + }, + { + .x = -12, .y = 0, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 6, + .priority = 3 + }, + { + .x = 4, .y = 0, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 8, + .priority = 3 + }, + { + .x = -12, .y = 8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 9, + .priority = 3 + }, + { + .x = 4, .y = 8, + SUBSPRITE_SHAPE(8, 8), + .tileOffset = 11, + .priority = 3 + }, +}; + +static const struct Subsprite sOamTable_48x48[] = { + { + .x = -24, + .y = -24, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 0, + .priority = 1 + }, + { + .x = 8, + .y = -24, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 4, + .priority = 1 + }, + { + .x = -24, + .y = -16, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 6, + .priority = 1 + }, + { + .x = 8, + .y = -16, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 10, + .priority = 1 + }, + { + .x = -24, + .y = -8, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 12, + .priority = 2 + }, + { + .x = 8, + .y = -8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 16, + .priority = 2 + }, + { + .x = -24, + .y = 0, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 18, + .priority = 2 + }, + { + .x = 8, + .y = 0, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 22, + .priority = 2 + }, + { + .x = -24, + .y = 8, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 24, + .priority = 2 + }, + { + .x = 8, + .y = 8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 28, + .priority = 2 + }, + { + .x = -24, + .y = 16, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 30, + .priority = 2 + }, + { + .x = 8, + .y = 16, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 34, + .priority = 2 + } +}; + +static const struct Subsprite sOamTable_48x48_4[] = { + { + .x = -24, + .y = -24, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 0, + .priority = 1 + }, + { + .x = 8, + .y = -24, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 4, + .priority = 1 + }, + { + .x = -24, + .y = -16, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 6, + .priority = 1 + }, + { + .x = 8, + .y = -16, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 10, + .priority = 1 + }, + { + .x = -24, + .y = -8, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 12, + .priority = 1 + }, + { + .x = 8, + .y = -8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 16, + .priority = 1 + }, + { + .x = -24, + .y = 0, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 18, + .priority = 1 + }, + { + .x = 8, + .y = 0, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 22, + .priority = 1 + }, + { + .x = -24, + .y = 8, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 24, + .priority = 1 + }, + { + .x = 8, + .y = 8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 28, + .priority = 1 + }, + { + .x = -24, + .y = 16, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 30, + .priority = 1 + }, + { + .x = 8, + .y = 16, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 34, + .priority = 1 + } +}; + +static const struct Subsprite sOamTable_48x48_HotSprings[] = { + { + .x = -24, + .y = -24, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 0, + .priority = 2 + }, + { + .x = 8, + .y = -24, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 4, + .priority = 2 + }, + { + .x = -24, + .y = -16, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 6, + .priority = 2 + }, + { + .x = 8, + .y = -16, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 10, + .priority = 2 + }, + { + .x = -24, + .y = -8, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 12, + .priority = 2 + }, + { + .x = 8, + .y = -8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 16, + .priority = 2 + }, + { + .x = -24, + .y = 0, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 18, + .priority = 2 + }, + { + .x = 8, + .y = 0, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 22, + .priority = 2 + }, + { + .x = -24, + .y = 8, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 24, + .priority = 2 + }, + { + .x = 8, + .y = 8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 28, + .priority = 2 + }, + { + .x = -24, + .y = 16, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 30, + .priority = 3 + }, + { + .x = 8, + .y = 16, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 34, + .priority = 3 + } +}; + +static const struct Subsprite sOamTable_48x48_Grass2[] = { + { + .x = -24, + .y = -24, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 0, + .priority = 2 + }, + { + .x = 8, + .y = -24, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 4, + .priority = 2 + }, + { + .x = -24, + .y = -16, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 6, + .priority = 2 + }, + { + .x = 8, + .y = -16, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 10, + .priority = 2 + }, + { + .x = -24, + .y = -8, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 12, + .priority = 2 + }, + { + .x = 8, + .y = -8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 16, + .priority = 2 + }, + { + .x = -24, + .y = 0, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 18, + .priority = 2 + }, + { + .x = 8, + .y = 0, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 22, + .priority = 2 + }, + { + .x = -24, + .y = 8, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 24, + .priority = 3 + }, + { + .x = 8, + .y = 8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 28, + .priority = 3 + }, + { + .x = -24, + .y = 16, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 30, + .priority = 3 + }, + { + .x = 8, + .y = 16, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 34, + .priority = 3 + } +}; + +static const struct Subsprite sOamTable_48x48_Grass1[] = { + { + .x = -24, + .y = -24, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 0, + .priority = 1 + }, + { + .x = 8, + .y = -24, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 4, + .priority = 1 + }, + { + .x = -24, + .y = -16, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 6, + .priority = 1 + }, + { + .x = 8, + .y = -16, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 10, + .priority = 1 + }, + { + .x = -24, + .y = -8, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 12, + .priority = 1 + }, + { + .x = 8, + .y = -8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 16, + .priority = 1 + }, + { + .x = -24, + .y = 0, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 18, + .priority = 1 + }, + { + .x = 8, + .y = 0, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 22, + .priority = 1 + }, + { + .x = -24, + .y = 8, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 24, + .priority = 3 + }, + { + .x = 8, + .y = 8, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 28, + .priority = 3 + }, + { + .x = -24, + .y = 16, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 30, + .priority = 3 + }, + { + .x = 8, + .y = 16, + SUBSPRITE_SHAPE(16, 8), + .tileOffset = 34, + .priority = 3 + } +}; + +static const struct Subsprite sOamTable_64x64_Follower[] = { + { + .x = -32, .y = -32, + SUBSPRITE_SHAPE(64, 32), + .tileOffset = 0, + .priority = 1 + }, + { + .x = -32, .y = 0, + SUBSPRITE_SHAPE(64, 32), + .tileOffset = 32, + .priority = 2 + } +}; + +static const struct Subsprite sOamTable_64x64_HotSprings[] = { + { + .x = -32, + .y = -32, + SUBSPRITE_SHAPE(64, 32), + .tileOffset = 0, + .priority = 2 + }, + { + .x = -32, + .y = 0, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 32, + .priority = 2 + }, + { + .x = 0, + .y = 0, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 36, + .priority = 2 + }, + { + .x = -32, + .y = 8, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 40, + .priority = 2 + }, + { + .x = 0, + .y = 8, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 44, + .priority = 2 + }, + { + .x = -32, + .y = 16, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 48, + .priority = 2 + }, + { + .x = 0, + .y = 16, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 52, + .priority = 2 + }, + { + .x = -32, + .y = 24, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 56, + .priority = 3 + }, + { + .x = 0, + .y = 24, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 60, + .priority = 3 + }, +}; + +static const struct Subsprite sOamTable_64x64_Grass2[] = { + { + .x = -32, + .y = -32, + SUBSPRITE_SHAPE(64, 32), + .tileOffset = 0, + .priority = 2 + }, + { + .x = -32, + .y = 0, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 32, + .priority = 2 + }, + { + .x = 0, + .y = 0, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 36, + .priority = 2 + }, + { + .x = -32, + .y = 8, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 40, + .priority = 2 + }, + { + .x = 0, + .y = 8, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 44, + .priority = 2 + }, + { + .x = -32, + .y = 16, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 48, + .priority = 3 + }, + { + .x = 0, + .y = 16, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 52, + .priority = 3 + }, + { + .x = -32, + .y = 24, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 56, + .priority = 3 + }, + { + .x = 0, + .y = 24, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 60, + .priority = 3 + }, +}; + +static const struct Subsprite sOamTable_64x64_Grass1[] = { + { + .x = -32, + .y = -32, + SUBSPRITE_SHAPE(64, 32), + .tileOffset = 0, + .priority = 1 + }, + { + .x = -32, + .y = 0, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 32, + .priority = 1 + }, + { + .x = 0, + .y = 0, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 36, + .priority = 1 + }, + { + .x = -32, + .y = 8, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 40, + .priority = 1 + }, + { + .x = 0, + .y = 8, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 44, + .priority = 1 + }, + { + .x = -32, + .y = 16, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 48, + .priority = 3 + }, + { + .x = 0, + .y = 16, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 52, + .priority = 3 + }, + { + .x = -32, + .y = 24, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 56, + .priority = 3 + }, + { + .x = 0, + .y = 24, + SUBSPRITE_SHAPE(32, 8), + .tileOffset = 60, + .priority = 3 + }, +}; + +static const struct Subsprite sOamTable_64x64_Grass3[] = { + { + .x = -32, + .y = -24, + SUBSPRITE_SHAPE(64, 32), + .tileOffset = 0, + .priority = 2 + }, + { + .x = -32, + .y = 8, + SUBSPRITE_SHAPE(64, 32), + .tileOffset = 32, + .priority = 3 + } +}; + +static const struct Subsprite sOamTable_64x64_Grass4[] = { + { + .x = -32, + .y = -24, + SUBSPRITE_SHAPE(64, 32), + .tileOffset = 0, + .priority = 1 + }, + { + .x = -32, + .y = 8, + SUBSPRITE_SHAPE(64, 32), + .tileOffset = 32, + .priority = 3 + } +}; + + +static const struct SubspriteTable sOamTables_16x24[] = { + SUBSPRITE_TABLE_ENTRY(sOamTable_16x24_0), + SUBSPRITE_TABLE_ENTRY(sOamTable_16x24_0), + SUBSPRITE_TABLE_ENTRY(sOamTable_16x24_1), + SUBSPRITE_TABLE_ENTRY(sOamTable_16x24_2), + SUBSPRITE_TABLE_ENTRY(sOamTable_16x24_3), + SUBSPRITE_TABLE_ENTRY(sOamTable_16x24_4), +}; + + +static const struct SubspriteTable sOamTables_24x16[] = { + SUBSPRITE_TABLE_ENTRY(sOamTable_24x16_0), + SUBSPRITE_TABLE_ENTRY(sOamTable_24x16_0), + SUBSPRITE_TABLE_ENTRY(sOamTable_24x16_1), + SUBSPRITE_TABLE_ENTRY(sOamTable_24x16_2), + SUBSPRITE_TABLE_ENTRY(sOamTable_24x16_3), + SUBSPRITE_TABLE_ENTRY(sOamTable_24x16_3), +}; + +static const struct SubspriteTable sOamTables_24x24[] = { + SUBSPRITE_TABLE_ENTRY(sOamTable_24x24_0), // reflections + SUBSPRITE_TABLE_ENTRY(sOamTable_24x24_0), // all 2 + SUBSPRITE_TABLE_ENTRY(sOamTable_24x24_1), // all 1 + SUBSPRITE_TABLE_ENTRY(sOamTable_24x24_2), // bottom 8 3 + SUBSPRITE_TABLE_ENTRY(sOamTable_24x24_3), // bottom 16 3 + SUBSPRITE_TABLE_ENTRY(sOamTable_24x24_4), // top 1, bottom 16 3 +}; + +static const struct SubspriteTable sOamTables_24x32[] = { + SUBSPRITE_TABLE_ENTRY(sOamTable_24x32_0), + SUBSPRITE_TABLE_ENTRY(sOamTable_24x32_0), + SUBSPRITE_TABLE_ENTRY(sOamTable_24x32_1), + SUBSPRITE_TABLE_ENTRY(sOamTable_24x32_2), + SUBSPRITE_TABLE_ENTRY(sOamTable_24x32_3), + SUBSPRITE_TABLE_ENTRY(sOamTable_24x32_4), +}; + + +static const struct SubspriteTable sOamTables_32x24[] = { + SUBSPRITE_TABLE_ENTRY(sOamTable_32x24_0), + SUBSPRITE_TABLE_ENTRY(sOamTable_32x24_0), + SUBSPRITE_TABLE_ENTRY(sOamTable_32x24_1), + SUBSPRITE_TABLE_ENTRY(sOamTable_32x24_2), + SUBSPRITE_TABLE_ENTRY(sOamTable_32x24_3), + SUBSPRITE_TABLE_ENTRY(sOamTable_32x24_4), +}; + + +static const struct SubspriteTable sOamTables_48x48[] = { + SUBSPRITE_TABLE_ENTRY(sOamTable_48x48), // reflections + SUBSPRITE_TABLE_ENTRY(sOamTable_48x48), // elevation 3 + SUBSPRITE_TABLE_ENTRY(sOamTable_48x48_4), // elevation 4 + SUBSPRITE_TABLE_ENTRY(sOamTable_48x48_HotSprings), // hot springs + SUBSPRITE_TABLE_ENTRY(sOamTable_48x48_Grass2), // long grass + SUBSPRITE_TABLE_ENTRY(sOamTable_48x48_Grass1) // long grass priority 1 +}; + + +// For following pokemon +// Makes the top 32 pixels priority 1, +// so that very tall pokemon's heads +// will appear on top of buildings, etc. +static const struct SubspriteTable sOamTables_64x64_Tall[] = { + {}, // unused + SUBSPRITE_TABLE_ENTRY(sOamTable_64x64_Follower), // elevation 3 + SUBSPRITE_TABLE_ENTRY(sOamTable_64x64_1), // elevation 4 + SUBSPRITE_TABLE_ENTRY(sOamTable_64x64_HotSprings), // hot springs + SUBSPRITE_TABLE_ENTRY(sOamTable_64x64_Grass2), // long grass + SUBSPRITE_TABLE_ENTRY(sOamTable_64x64_Grass1) // long grass priority 1 +}; + +// Like sOamTables_64x64_Tall, but fewer pixels visible in long grass +// Meant for pokemon that are more long than tall like Wailord +static const struct SubspriteTable sOamTables_64x64_Long[] = { + {}, // unused + SUBSPRITE_TABLE_ENTRY(sOamTable_64x64_Follower), // elevation 3 + SUBSPRITE_TABLE_ENTRY(sOamTable_64x64_1), // elevation 4 + SUBSPRITE_TABLE_ENTRY(sOamTable_64x64_HotSprings), // hot springs + SUBSPRITE_TABLE_ENTRY(sOamTable_64x64_Grass3), // long grass + SUBSPRITE_TABLE_ENTRY(sOamTable_64x64_Grass4) // long grass priority 1 +}; +#endif \ No newline at end of file diff --git a/src/event_object_movement.c b/src/event_object_movement.c index d96e4ad4e5..7c3163b686 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -6749,19 +6749,26 @@ bool8 MovementAction_ExitPokeball_Step1(struct ObjectEvent *objectEvent, struct return TRUE; // Set graphics, palette, and affine animation } else if ((duration == 0 && sprite->data[3] == 3) || (duration == 1 && sprite->data[3] == 7)) { - FollowerSetGraphics(objectEvent, objectEvent->extra.mon.species, objectEvent->extra.mon.form, objectEvent->extra.mon.shiny); - LoadFillColorPalette(RGB_WHITE, OBJ_EVENT_PAL_TAG_WHITE, sprite); - // Initialize affine animation - sprite->affineAnims = sAffineAnims_PokeballFollower; - sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL; - InitSpriteAffineAnim(sprite); - StartSpriteAffineAnim(sprite, sprite->data[6] >> 4); + FollowerSetGraphics(objectEvent, objectEvent->extra.mon.species, objectEvent->extra.mon.form, objectEvent->extra.mon.shiny); + LoadFillColorPalette(RGB_WHITE, OBJ_EVENT_PAL_TAG_WHITE, sprite); + // Initialize affine animation + sprite->affineAnims = sAffineAnims_PokeballFollower; + #if LARGE_OW_SUPPORT + if (IS_POW_OF_TWO(-sprite->centerToCornerVecX)) { + #endif + sprite->affineAnims = sAffineAnims_PokeballFollower; + sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL; + InitSpriteAffineAnim(sprite); + StartSpriteAffineAnim(sprite, sprite->data[6] >> 4); + #if LARGE_OW_SUPPORT + } + #endif // Restore original palette & disable affine } else if ((duration == 0 && sprite->data[3] == 1) || (duration == 1 && sprite->data[3] == 3)) { - sprite->affineAnimEnded = TRUE; - FreeSpriteOamMatrix(sprite); - sprite->oam.affineMode = ST_OAM_AFFINE_OFF; - FollowerSetGraphics(objectEvent, objectEvent->extra.mon.species, objectEvent->extra.mon.form, objectEvent->extra.mon.shiny); + sprite->affineAnimEnded = TRUE; + FreeSpriteOamMatrix(sprite); + sprite->oam.affineMode = ST_OAM_AFFINE_OFF; + FollowerSetGraphics(objectEvent, objectEvent->extra.mon.species, objectEvent->extra.mon.form, objectEvent->extra.mon.shiny); } return FALSE; } @@ -6782,20 +6789,26 @@ bool8 MovementAction_EnterPokeball_Step1(struct ObjectEvent *objectEvent, struct sprite->data[2] = 2; return FALSE; } else if (sprite->data[3] == 11) { // Set palette to white & start affine - LoadFillColorPalette(RGB_WHITE, OBJ_EVENT_PAL_TAG_WHITE, sprite); - sprite->affineAnims = sAffineAnims_PokeballFollower; - sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL; - #if LARGE_OW_SUPPORT - sprite->subspriteTableNum = 1; - #endif - InitSpriteAffineAnim(sprite); - StartSpriteAffineAnim(sprite, sprite->data[6]); + LoadFillColorPalette(RGB_WHITE, OBJ_EVENT_PAL_TAG_WHITE, sprite); + #if LARGE_OW_SUPPORT + // Only do affine if sprite width is power of 2 + // (effect looks weird on sprites composed of subsprites like 48x48, etc) + if (IS_POW_OF_TWO(-sprite->centerToCornerVecX)) { + #endif + sprite->affineAnims = sAffineAnims_PokeballFollower; + sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL; + InitSpriteAffineAnim(sprite); + StartSpriteAffineAnim(sprite, sprite->data[6]); + #if LARGE_OW_SUPPORT + } + #endif + sprite->subspriteTableNum = 0; } else if (sprite->data[3] == 7) { // Free white palette and change to pokeball, disable affine - sprite->affineAnimEnded = TRUE; - FreeSpriteOamMatrix(sprite); - sprite->oam.affineMode = ST_OAM_AFFINE_OFF; - ObjectEventSetGraphicsId(objectEvent, OBJ_EVENT_GFX_ANIMATED_BALL); - objectEvent->inanimate = FALSE; + sprite->affineAnimEnded = TRUE; + FreeSpriteOamMatrix(sprite); + sprite->oam.affineMode = ST_OAM_AFFINE_OFF; + ObjectEventSetGraphicsId(objectEvent, OBJ_EVENT_GFX_ANIMATED_BALL); + objectEvent->inanimate = FALSE; } return FALSE; } @@ -8853,9 +8866,6 @@ void ObjectEventUpdateElevation(struct ObjectEvent *objEvent, struct Sprite *spr #endif return; } - #if LARGE_OW_SUPPORT - sprite->subspriteMode = SUBSPRITES_ON; - #endif objEvent->currentElevation = curElevation; @@ -9246,6 +9256,9 @@ static void DoGroundEffects_OnSpawn(struct ObjectEvent *objEvent, struct Sprite if (objEvent->triggerGroundEffectsOnMove) { flags = 0; + #if LARGE_OW_SUPPORT + sprite->subspriteMode = SUBSPRITES_ON; + #endif UpdateObjectEventElevationAndPriority(objEvent, sprite); GetAllGroundEffectFlags_OnSpawn(objEvent, &flags); SetObjectEventSpriteOamTableForLongGrass(objEvent, sprite); @@ -9262,6 +9275,9 @@ static void DoGroundEffects_OnBeginStep(struct ObjectEvent *objEvent, struct Spr if (objEvent->triggerGroundEffectsOnMove) { flags = 0; + #if LARGE_OW_SUPPORT + sprite->subspriteMode = SUBSPRITES_ON; + #endif UpdateObjectEventElevationAndPriority(objEvent, sprite); GetAllGroundEffectFlags_OnBeginStep(objEvent, &flags); SetObjectEventSpriteOamTableForLongGrass(objEvent, sprite); diff --git a/src/field_effect_helpers.c b/src/field_effect_helpers.c index 3d4f0ce6bd..7bc0779635 100755 --- a/src/field_effect_helpers.c +++ b/src/field_effect_helpers.c @@ -13,11 +13,15 @@ #include "trig.h" #include "constants/event_objects.h" #include "constants/field_effects.h" +#include "constants/rgb.h" #include "constants/songs.h" #define OBJ_EVENT_PAL_TAG_NONE 0x11FF // duplicate of define in event_object_movement.c #define PAL_TAG_REFLECTION_OFFSET 0x2000 // reflection tag value is paletteTag + 0x2000 #define PAL_RAW_REFLECTION_OFFSET 0x4000 // raw reflection tag is paletteNum + 0x4000 +#define HIGH_BRIDGE_PAL_TAG 0x4010 +// Build a unique tag for reflection's palette based on based tag, or paletteNum +#define REFLECTION_PAL_TAG(tag, num) ((tag) == TAG_NONE ? (num) + PAL_RAW_REFLECTION_OFFSET : (tag) + PAL_TAG_REFLECTION_OFFSET) static void UpdateObjectReflectionSprite(struct Sprite *); static void LoadObjectReflectionPalette(struct ObjectEvent *objectEvent, struct Sprite *sprite); @@ -65,8 +69,9 @@ void SetUpReflection(struct ObjectEvent *objectEvent, struct Sprite *sprite, boo StartSpriteAnim(reflectionSprite, 0); reflectionSprite->affineAnims = gDummySpriteAffineAnimTable; reflectionSprite->affineAnimBeginning = TRUE; - reflectionSprite->subspriteMode = SUBSPRITES_OFF; - reflectionSprite->sReflectionObjEventId = sprite->data[0]; + reflectionSprite->subspriteMode = SUBSPRITES_IGNORE_PRIORITY; + reflectionSprite->subspriteTableNum = 0; + reflectionSprite->sReflectionObjEventId = sprite->sReflectionObjEventId; reflectionSprite->sReflectionObjEventLocalId = objectEvent->localId; reflectionSprite->sIsStillReflection = stillReflection; LoadObjectReflectionPalette(objectEvent, reflectionSprite); @@ -93,7 +98,7 @@ static void LoadObjectReflectionPalette(struct ObjectEvent *objectEvent, struct && ((bridgeType = MetatileBehavior_GetBridgeType(objectEvent->previousMetatileBehavior)) || (bridgeType = MetatileBehavior_GetBridgeType(objectEvent->currentMetatileBehavior)))) { - reflectionSprite->data[2] = bridgeReflectionVerticalOffsets[bridgeType - 1]; + reflectionSprite->sReflectionVerticalOffset = bridgeReflectionVerticalOffsets[bridgeType - 1]; LoadObjectHighBridgeReflectionPalette(objectEvent, reflectionSprite); } else @@ -104,76 +109,71 @@ static void LoadObjectReflectionPalette(struct ObjectEvent *objectEvent, struct // Apply a blue tint effect to a palette static void ApplyPondFilter(u8 paletteNum, u16 *dest) { - u8 i, val, r, g, b; - // CpuCopy16(gPlttBufferUnfaded + 0x100 + paletteNum * 16, dest, 32); - u16 *src = gPlttBufferUnfaded + 0x100 + paletteNum * 16; - for (i = 0; i < 16; i++) { - r = src[i] & 0x1F; - g = (src[i] >> 5) & 0x1F; - b = (src[i] >> 10) & 0x1F; - b += 10; - if (b > 31) - b = 31; - *dest++ = (b << 10) | (g << 5) | r; - } + u32 i, r, g, b; + // CpuCopy16(gPlttBufferUnfaded + 0x100 + paletteNum * 16, dest, 32); + u16 *src = gPlttBufferUnfaded + OBJ_PLTT_ID(paletteNum); + *dest++ = *src++; // copy transparency + for (i = 0; i < 16 - 1; i++) { + r = GET_R(src[i]); + g = GET_G(src[i]); + b = GET_B(src[i]); + b += 10; + if (b > 31) + b = 31; + *dest++ = RGB2(r, g, b); + } } // Apply a ice tint effect to a palette static void ApplyIceFilter(u8 paletteNum, u16 *dest) { - u8 i, val, r, g, b; - // CpuCopy16(gPlttBufferUnfaded + 0x100 + paletteNum * 16, dest, 32); - u16 *src = gPlttBufferUnfaded + 0x100 + paletteNum * 16; - for (i = 0; i < 16; i++) { - r = src[i] & 0x1F; - r -= 5; - if (r > 31) - r = 0; - g = (src[i] >> 5) & 0x1F; - g += 3; - if (g > 31) - g = 31; - b = (src[i] >> 10) & 0x1F; - b += 16; - if (b > 31) - b = 31; - *dest++ = (b << 10) | (g << 5) | r; - } + u32 i, r, g, b; + // CpuCopy16(gPlttBufferUnfaded + 0x100 + paletteNum * 16, dest, 32); + u16 *src = gPlttBufferUnfaded + OBJ_PLTT_ID(paletteNum); + *dest++ = *src++; // copy transparency + for (i = 0; i < 16 - 1; i++) { + r = GET_R(src[i]); + r -= 5; + if (r > 31) + r = 0; + g = GET_G(src[i]); + g += 3; + if (g > 31) + g = 31; + b = GET_B(src[i]); + b += 16; + if (b > 31) + b = 31; + *dest++ = RGB2(r, g, b); + } } static void LoadObjectRegularReflectionPalette(struct ObjectEvent *objectEvent, struct Sprite *sprite) { - const struct ObjectEventGraphicsInfo *graphicsInfo = GetObjectEventGraphicsInfo(objectEvent->graphicsId); const struct Sprite *mainSprite = &gSprites[objectEvent->spriteId]; u16 baseTag = GetSpritePaletteTagByPaletteNum(mainSprite->oam.paletteNum); - u16 paletteTag = baseTag == 0xFFFF ? mainSprite->oam.paletteNum + PAL_RAW_REFLECTION_OFFSET : baseTag + PAL_TAG_REFLECTION_OFFSET; + u16 paletteTag = REFLECTION_PAL_TAG(baseTag, mainSprite->oam.paletteNum); u8 paletteNum = IndexOfSpritePaletteTag(paletteTag); - if (paletteNum == 0xFF) { // Load filtered palette - u16 filteredData[16] = {0}; - struct SpritePalette filteredPalette = {.tag = paletteTag, .data = filteredData}; - if (sprite->data[7] == FALSE) { - ApplyPondFilter(mainSprite->oam.paletteNum, filteredData); - } else { - ApplyIceFilter(mainSprite->oam.paletteNum, filteredData); - } - paletteNum = LoadSpritePalette(&filteredPalette); - UpdateSpritePaletteWithWeather(paletteNum); + if (paletteNum <= 16) { // Load filtered palette + u16 filteredData[16]; + struct SpritePalette filteredPal = {.tag = paletteTag, .data = filteredData}; + if (sprite->sIsStillReflection == FALSE) + ApplyPondFilter(mainSprite->oam.paletteNum, filteredData); + else + ApplyIceFilter(mainSprite->oam.paletteNum, filteredData); + paletteNum = LoadSpritePalette(&filteredPal); + UpdateSpritePaletteWithWeather(paletteNum); } sprite->oam.paletteNum = paletteNum; - sprite->oam.objMode = 1; // Alpha blending + sprite->oam.objMode = ST_OAM_OBJ_BLEND; } -#define HIGH_BRIDGE_PAL_TAG 0x4010 - // When walking on a bridge high above water (Route 120), the reflection is a solid dark blue color. // This is so the sprite blends in with the dark water metatile underneath the bridge. static void LoadObjectHighBridgeReflectionPalette(struct ObjectEvent *objectEvent, struct Sprite *sprite) { - u16 blueData[16] = {0}; + u16 blueData[16]; struct SpritePalette bluePalette = {.tag = HIGH_BRIDGE_PAL_TAG, .data = blueData}; - u8 i; - for (i = 1; i < 16; i++) { - blueData[i] = 0x55c9; - } + CpuFill16(0x55C9, blueData, PLTT_SIZE_4BPP); sprite->oam.paletteNum = LoadSpritePalette(&bluePalette); UpdateSpritePaletteWithWeather(sprite->oam.paletteNum); } @@ -183,7 +183,7 @@ static void UpdateObjectReflectionSprite(struct Sprite *reflectionSprite) struct ObjectEvent *objectEvent = &gObjectEvents[reflectionSprite->data[0]]; struct Sprite *mainSprite = &gSprites[objectEvent->spriteId]; - if (!objectEvent->active || !objectEvent->hasReflection || objectEvent->localId != reflectionSprite->data[1]) + if (!objectEvent->active || !objectEvent->hasReflection || objectEvent->localId != reflectionSprite->sReflectionObjEventLocalId) { reflectionSprite->inUse = FALSE; FieldEffectFreePaletteIfUnused(reflectionSprite->oam.paletteNum); @@ -191,37 +191,37 @@ static void UpdateObjectReflectionSprite(struct Sprite *reflectionSprite) } // Only filter palette if not using the high bridge blue palette + // This is basically a copy of LoadObjectRegularReflectionPalette if (IndexOfSpritePaletteTag(HIGH_BRIDGE_PAL_TAG) != reflectionSprite->oam.paletteNum) { - u16 baseTag = GetSpritePaletteTagByPaletteNum(mainSprite->oam.paletteNum); - u16 paletteTag = baseTag == 0xFFFF ? mainSprite->oam.paletteNum + PAL_RAW_REFLECTION_OFFSET : baseTag + PAL_TAG_REFLECTION_OFFSET; - u8 paletteNum = IndexOfSpritePaletteTag(paletteTag); - if (paletteNum == 0xFF) { // Build filtered palette - u16 filteredData[16] = {0}; - struct SpritePalette filteredPalette = {.tag = paletteTag, .data = filteredData}; - // Free palette if unused - reflectionSprite->inUse = FALSE; - FieldEffectFreePaletteIfUnused(reflectionSprite->oam.paletteNum); - reflectionSprite->inUse = TRUE; - if (reflectionSprite->data[7] == FALSE) { - ApplyPondFilter(mainSprite->oam.paletteNum, filteredData); - } else { - ApplyIceFilter(mainSprite->oam.paletteNum, filteredData); + u16 baseTag = GetSpritePaletteTagByPaletteNum(mainSprite->oam.paletteNum); + u16 paletteTag = REFLECTION_PAL_TAG(baseTag, mainSprite->oam.paletteNum); + u8 paletteNum = IndexOfSpritePaletteTag(paletteTag); + if (paletteNum >= 16) { // Build filtered palette + u16 filteredData[16]; + struct SpritePalette filteredPal = {.tag = paletteTag, .data = filteredData}; + // Free palette if unused + reflectionSprite->inUse = FALSE; + FieldEffectFreePaletteIfUnused(reflectionSprite->oam.paletteNum); + reflectionSprite->inUse = TRUE; + if (reflectionSprite->sIsStillReflection == FALSE) { + ApplyPondFilter(mainSprite->oam.paletteNum, filteredData); + } else { + ApplyIceFilter(mainSprite->oam.paletteNum, filteredData); + } + paletteNum = LoadSpritePalette(&filteredPal); + UpdateSpritePaletteWithWeather(paletteNum); } - paletteNum = LoadSpritePalette(&filteredPalette); - UpdateSpritePaletteWithWeather(paletteNum); - } - reflectionSprite->oam.paletteNum = paletteNum; + reflectionSprite->oam.paletteNum = paletteNum; } reflectionSprite->oam.shape = mainSprite->oam.shape; reflectionSprite->oam.size = mainSprite->oam.size; reflectionSprite->oam.matrixNum = mainSprite->oam.matrixNum | ST_OAM_VFLIP; reflectionSprite->oam.tileNum = mainSprite->oam.tileNum; reflectionSprite->subspriteTables = mainSprite->subspriteTables; - reflectionSprite->subspriteTableNum = mainSprite->subspriteTableNum; reflectionSprite->invisible = mainSprite->invisible; reflectionSprite->x = mainSprite->x; - // reflectionSprite->data[2] holds an additional vertical offset, used by the high bridges on Route 120 - reflectionSprite->y = mainSprite->y + GetReflectionVerticalOffset(objectEvent) + reflectionSprite->data[2]; + // sReflectionVerticalOffset is only set for high bridges + reflectionSprite->y = mainSprite->y + GetReflectionVerticalOffset(objectEvent) + reflectionSprite->sReflectionVerticalOffset; reflectionSprite->centerToCornerVecX = mainSprite->centerToCornerVecX; reflectionSprite->centerToCornerVecY = mainSprite->centerToCornerVecY; reflectionSprite->x2 = mainSprite->x2; @@ -231,15 +231,17 @@ static void UpdateObjectReflectionSprite(struct Sprite *reflectionSprite) if (objectEvent->hideReflection == TRUE) reflectionSprite->invisible = TRUE; - // Check if the reflection is not still. - if (reflectionSprite->data[7] == FALSE) + // Support "virtual" sprites which can't be rotated via affines + if (reflectionSprite->subspriteTables[0].subsprites) { + reflectionSprite->oam.affineMode = ST_OAM_AFFINE_OFF; + return; + } + if (reflectionSprite->sIsStillReflection == FALSE) { - // Sets the reflection sprite's rot/scale matrix to the appropriate - // matrix based on whether or not the main sprite is horizontally flipped. - // If the sprite is facing to the east, then it is flipped, and its matrixNum is 8. - reflectionSprite->oam.matrixNum = 0; - if (mainSprite->oam.matrixNum & ST_OAM_HFLIP) - reflectionSprite->oam.matrixNum = 1; + // Sets the reflection sprite's rot/scale matrix to the correct + // water reflection matrix based on the main sprite's facing direction. + // If the sprite is facing east, then it's flipped, and its matrixNum is 1. + reflectionSprite->oam.matrixNum = (mainSprite->oam.matrixNum & ST_OAM_HFLIP) ? 1 : 0; } } From 94a2e04fc65ffb58545aa371e8b7a612ad590aa2 Mon Sep 17 00:00:00 2001 From: Ariel A <24759293+aarant@users.noreply.github.com> Date: Thu, 12 Oct 2023 00:34:38 -0400 Subject: [PATCH 2/2] Made Deoxys rock palette dynamic. --- src/field_specials.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/field_specials.c b/src/field_specials.c index 5b950a4fa8..87674d8ce7 100644 --- a/src/field_specials.c +++ b/src/field_specials.c @@ -3260,7 +3260,6 @@ void ScrollableMultichoice_ClosePersistentMenu(void) #undef tTaskId #define DEOXYS_ROCK_LEVELS 11 -#define ROCK_PAL_ID 10 void DoDeoxysRockInteraction(void) { @@ -3337,11 +3336,13 @@ static void Task_DeoxysRockInteraction(u8 taskId) } } +// duplicate of event_object_movement +#define OBJ_EVENT_PAL_TAG_BIRTH_ISLAND_STONE 0x111F + static void ChangeDeoxysRockLevel(u8 rockLevel) { - u8 objectEventId; - LoadPalette(&sDeoxysRockPalettes[rockLevel], OBJ_PLTT_ID(ROCK_PAL_ID), PLTT_SIZEOF(4)); - TryGetObjectEventIdByLocalIdAndMap(LOCALID_BIRTH_ISLAND_EXTERIOR_ROCK, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectEventId); + u8 paletteNum = IndexOfSpritePaletteTag(OBJ_EVENT_PAL_TAG_BIRTH_ISLAND_STONE); + LoadPalette(&sDeoxysRockPalettes[rockLevel], OBJ_PLTT_ID(paletteNum), PLTT_SIZEOF(4)); if (rockLevel == 0) PlaySE(SE_M_CONFUSE_RAY); // Failure sound @@ -3387,10 +3388,13 @@ void IncrementBirthIslandRockStepCount(void) } } +// called before fade-in void SetDeoxysRockPalette(void) { - LoadPalette(&sDeoxysRockPalettes[(u8)VarGet(VAR_DEOXYS_ROCK_LEVEL)], OBJ_PLTT_ID(ROCK_PAL_ID), PLTT_SIZEOF(4)); - BlendPalettes(1 << (ROCK_PAL_ID + 16), 16, 0); + u32 paletteNum = IndexOfSpritePaletteTag(OBJ_EVENT_PAL_TAG_BIRTH_ISLAND_STONE); + LoadPalette(&sDeoxysRockPalettes[(u8)VarGet(VAR_DEOXYS_ROCK_LEVEL)], OBJ_PLTT_ID(paletteNum), PLTT_SIZEOF(4)); + // Set faded to all black, weather blending handled during fade-in + CpuFill16(0, &gPlttBufferFaded[OBJ_PLTT_ID(paletteNum)], 32); } void SetPCBoxToSendMon(u8 boxId)