summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/battle_setup.c3
-rw-r--r--src/field_effect.c3
-rw-r--r--src/field_screen_effect.c4
-rw-r--r--src/fieldmap.c3
-rw-r--r--src/fldeff_groundshake.c322
-rw-r--r--src/fldeff_sweetscent.c5
-rw-r--r--src/fossil_specials.c561
-rw-r--r--src/mirage_tower.c868
-rw-r--r--src/overworld.c10
-rwxr-xr-xsrc/roulette_util.c424
10 files changed, 977 insertions, 1226 deletions
diff --git a/src/battle_setup.c b/src/battle_setup.c
index 56bed77c8..55ee331cd 100644
--- a/src/battle_setup.c
+++ b/src/battle_setup.c
@@ -40,6 +40,7 @@
#include "fldeff.h"
#include "fldeff_misc.h"
#include "field_control_avatar.h"
+#include "mirage_tower.h"
#include "constants/map_types.h"
#include "constants/battle_frontier.h"
@@ -341,7 +342,7 @@ static void Task_BattleStart(u8 taskId)
if (!FldEffPoison_IsActive()) // is poison not active?
{
BattleTransition_StartOnField(tTransition);
- sub_81BE72C();
+ ClearMirageTowerPulseBlendEffect();
tState++; // go to case 1.
}
break;
diff --git a/src/field_effect.c b/src/field_effect.c
index 4e6f81484..9a65a444b 100644
--- a/src/field_effect.c
+++ b/src/field_effect.c
@@ -12,6 +12,7 @@
#include "fldeff.h"
#include "gpu_regs.h"
#include "main.h"
+#include "mirage_tower.h"
#include "menu.h"
#include "metatile_behavior.h"
#include "overworld.h"
@@ -2325,7 +2326,7 @@ static void TeleportFieldEffectTask4(struct Task *task)
{
if (task->data[5] == FALSE)
{
- sub_81BE72C();
+ ClearMirageTowerPulseBlendEffect();
task->data[5] = TRUE;
}
diff --git a/src/field_screen_effect.c b/src/field_screen_effect.c
index b0572b393..a6b7e7c24 100644
--- a/src/field_screen_effect.c
+++ b/src/field_screen_effect.c
@@ -17,6 +17,7 @@
#include "load_save.h"
#include "main.h"
#include "menu.h"
+#include "mirage_tower.h"
#include "event_obj_lock.h"
#include "metatile_behavior.h"
#include "palette.h"
@@ -34,7 +35,6 @@
extern bool32 sub_81D6534(void);
extern bool8 walkrun_is_standing_still(void);
extern void ScriptUnfreezeEventObjects(void);
-extern void sub_81BE72C(void);
extern void sub_80FB768(void);
extern void sub_808D194(void);
extern void sub_808D1C8(void);
@@ -673,7 +673,7 @@ static void sub_80AFA0C(u8 taskId)
{
if (task->data[1] == 0)
{
- sub_81BE72C();
+ ClearMirageTowerPulseBlendEffect();
task->data[1] = 1;
}
if (BGMusicStopped())
diff --git a/src/fieldmap.c b/src/fieldmap.c
index 5f9d22558..4efbc1234 100644
--- a/src/fieldmap.c
+++ b/src/fieldmap.c
@@ -5,6 +5,7 @@
#include "fldeff_misc.h"
#include "frontier_util.h"
#include "menu.h"
+#include "mirage_tower.h"
#include "overworld.h"
#include "palette.h"
#include "pokenav.h"
@@ -762,7 +763,7 @@ bool8 CameraMove(int x, int y)
else
{
save_serialize_map();
- sub_81BE72C();
+ ClearMirageTowerPulseBlendEffect();
old_x = gSaveBlock1Ptr->pos.x;
old_y = gSaveBlock1Ptr->pos.y;
connection = sub_8088950(direction, gSaveBlock1Ptr->pos.x, gSaveBlock1Ptr->pos.y);
diff --git a/src/fldeff_groundshake.c b/src/fldeff_groundshake.c
deleted file mode 100644
index bfd583981..000000000
--- a/src/fldeff_groundshake.c
+++ /dev/null
@@ -1,322 +0,0 @@
-#include "global.h"
-#include "event_data.h"
-#include "event_object_movement.h"
-#include "field_camera.h"
-#include "fldeff.h"
-#include "alloc.h"
-#include "random.h"
-#include "roulette_util.h"
-#include "script.h"
-#include "sound.h"
-#include "sprite.h"
-#include "task.h"
-#include "constants/flags.h"
-#include "constants/maps.h"
-#include "constants/songs.h"
-
-// structures
-struct Struct203CF18 {
- u8 taskId;
- struct InnerStruct203CF18 unk4;
-}; //size = 0xC8
-
-// extern data
-extern const struct SpriteSheet gUnknown_08617D94[];
-extern const s16 gUnknown_08617D64[][3];
-
-// static functions
-static void sub_81BE808(u8 taskId);
-static void sub_81BE900(u8 taskId);
-static void sub_81BE968(void);
-static void sub_81BE9C0(u8 taskId);
-static void sub_81BEA00(u8 taskId);
-static void sub_81BEA20(void);
-static void sub_81BEAD8(struct Sprite* sprite);
-
-// rodata
-const struct InnerStruct203CF18_3 gUnknown_08617E18 = {
- .unk0 = 0x433b,
- .unk2 = 0x61,
- .unk4 = 0x0F,
- .unk5 = 0x05,
- .unk6 = 0xFF,
- .unk7_0 = 0xB,
- .unk7_4 = 0x1,
- .unk7_6 = 0,
- .unk7_7 = 1,
-};
-
-static const union AnimCmd gSpriteAnim_8617E20[] =
-{
- ANIMCMD_FRAME(0, 12),
- ANIMCMD_JUMP(0),
-};
-
-static const union AnimCmd *const gSpriteAnimTable_8617E28[] =
-{
- gSpriteAnim_8617E20,
-};
-
-static const struct OamData gUnknown_08617E2C =
-{
- .y = 0,
- .affineMode = 0,
- .objMode = 0,
- .mosaic = 0,
- .bpp = 0,
- .shape = 0,
- .x = 0,
- .matrixNum = 0,
- .size = 0,
- .tileNum = 0,
- .priority = 0,
- .paletteNum = 0,
- .affineParam = 0,
-};
-
-static const struct SpriteTemplate gUnknown_08617E34 = {
- .tileTag = 0x0FA0,
- .paletteTag = 0xFFFF,
- .oam = &gUnknown_08617E2C,
- .anims = gSpriteAnimTable_8617E28,
- .images = NULL,
- .affineAnims = gDummySpriteAffineAnimTable,
- .callback = sub_81BEAD8
-};
-
-static const union AnimCmd gSpriteAnim_8617E4C[] =
-{
- ANIMCMD_FRAME(0, 12),
- ANIMCMD_JUMP(0),
-};
-
-static const union AnimCmd *const gSpriteAnim_8617E54[] =
-{
- gSpriteAnim_8617E4C,
-};
-
-static const struct OamData gSpriteAnim_8617E58 =
-{
- .y = 0,
- .affineMode = 0,
- .objMode = 0,
- .mosaic = 0,
- .bpp = 0,
- .shape = 0,
- .x = 0,
- .matrixNum = 0,
- .size = 1,
- .tileNum = 0,
- .priority = 0,
- .paletteNum = 0,
- .affineParam = 0,
-};
-
-static const struct SpriteTemplate gUnknown_08617E60 = {
- .tileTag = 0x0FA0,
- .paletteTag = 0xFFFF,
- .oam = &gSpriteAnim_8617E58,
- .anims = gSpriteAnim_8617E54,
- .images = NULL,
- .affineAnims = gDummySpriteAffineAnimTable,
- .callback = sub_81BEAD8
-};
-
-// ewram
-EWRAM_DATA struct Struct203CF18 *gUnknown_0203CF18 = NULL;
-
-// text
-bool8 sub_81BE66C(void)
-{
- if (!(gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(ROUTE111) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE111)))
- return FALSE;
- else
- return FlagGet(FLAG_0x14E);
-}
-
-static void sub_81BE698(u8 taskId)
-{
- sub_8151E50(&(gUnknown_0203CF18->unk4));
-}
-
-void sub_81BE6AC(void)
-{
- gUnknown_0203CF18 = NULL;
-}
-
-void sub_81BE6B8(void)
-{
- if (gUnknown_0203CF18 != NULL)
- {
- gUnknown_0203CF18 = NULL;
- return;
- }
-
- if (gSaveBlock1Ptr->location.mapGroup != MAP_GROUP(ROUTE111) || gSaveBlock1Ptr->location.mapNum != MAP_NUM(ROUTE111) || !FlagGet(FLAG_0x14E))
- return;
-
- gUnknown_0203CF18 = (struct Struct203CF18 *)AllocZeroed(sizeof(struct Struct203CF18));
- sub_8151B3C(&(gUnknown_0203CF18->unk4));
- sub_8151B68(&(gUnknown_0203CF18->unk4), &gUnknown_08617E18);
- sub_8151CA8(&(gUnknown_0203CF18->unk4), 1, 1);
- gUnknown_0203CF18->taskId = CreateTask(sub_81BE698, 0xFF);
-}
-
-void sub_81BE72C(void)
-{
- if (gSaveBlock1Ptr->location.mapGroup != MAP_GROUP(ROUTE111) || gSaveBlock1Ptr->location.mapNum != MAP_NUM(ROUTE111)
- || !FlagGet(FLAG_0x14E) || gUnknown_0203CF18 == NULL)
- return;
-
- if( FuncIsActiveTask(sub_81BE698))
- DestroyTask(gUnknown_0203CF18->taskId);
-
- sub_8151D28(&(gUnknown_0203CF18->unk4), 1, 1);
- sub_8151C50(&(gUnknown_0203CF18->unk4), 1, 1);
- Free(gUnknown_0203CF18);
- gUnknown_0203CF18 = NULL;
-}
-
-void sub_81BE79C(void)
-{
- u16 rand;
- bool8 chance;
-
- if (VarGet(VAR_0x40CB) != 0)
- {
- FlagClear(FLAG_0x14E);
- return;
- }
- rand = Random();
- chance = rand & 1;
- if (FlagGet(FLAG_0x09D) == TRUE)
- chance = TRUE;
- if (chance)
- {
- FlagSet(FLAG_0x14E);
- sub_81BE6B8();
- return;
- }
- FlagClear(FLAG_0x14E);
-}
-
-void sub_81BE7F4(void)
-{
- CreateTask(sub_81BE808, 0x8);
-}
-
-static void sub_81BE808(u8 taskId)
-{
- u8 eventObjectIdBuffer;
- struct EventObject *fieldEventObject;
- struct EventObject *playerAvatarEventObject;
-
- TryGetEventObjectIdByLocalIdAndMap(0x2D, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &eventObjectIdBuffer);
- fieldEventObject = &(gEventObjects[eventObjectIdBuffer]);
- gSprites[fieldEventObject->spriteId].pos2.y += 4;
- playerAvatarEventObject = &(gEventObjects[gPlayerAvatar.eventObjectId]);
-
- if((gSprites[fieldEventObject->spriteId].pos1.y + gSprites[fieldEventObject->spriteId].pos2.y) >=
- (gSprites[playerAvatarEventObject->spriteId].pos1.y + gSprites[playerAvatarEventObject->spriteId].pos2.y))
- {
- DestroyTask(taskId);
- EnableBothScriptContexts();
- }
-}
-
-static void sp136_strengh_sound(u8 a, u8 b, u8 c, u8 d)
-{
- u8 taskId;
-
- taskId = CreateTask(sub_81BE900, 0x9);
- gTasks[taskId].data[0] = b;
- gTasks[taskId].data[1] = 0;
- gTasks[taskId].data[2] = c;
- gTasks[taskId].data[3] = d;
- gTasks[taskId].data[4] = a;
- SetCameraPanningCallback(NULL);
- PlaySE(SE_W070);
-}
-
-static void sub_81BE900(u8 taskId)
-{
- s16 *data = gTasks[taskId].data;
-
- data[1]++;
- if ((data[1] % data[3]) == 0)
- {
- data[1] = 0;
- data[2]--;
- data[0] = -data[0];
- data[4] = -data[4];
- SetCameraPanning(data[0], data[4]);
- if (!data[2])
- {
- sub_81BE968();
- DestroyTask(taskId);
- InstallCameraPanAheadCallback();
- }
- }
-}
-
-static void sub_81BE968(void)
-{
- u8 taskId = FindTaskIdByFunc(sub_81BE9C0);
- if (taskId != 0xFF)
- gTasks[taskId].data[0]++;
-}
-
-void sub_81BE994(void)
-{
- LoadSpriteSheets(gUnknown_08617D94);
- sub_81BEA20();
- CreateTask(sub_81BE9C0, 0x8);
- sp136_strengh_sound(2, 1, 16, 3);
-}
-
-static void sub_81BE9C0(u8 taskId)
-{
- u16 *data = gTasks[taskId].data;
-
- if (++data[1] == 1000 || data[0] == 17)
- gTasks[taskId].func = sub_81BEA00;
-}
-
-static void sub_81BEA00(u8 taskId)
-{
- FreeSpriteTilesByTag(4000);
- DestroyTask(taskId);
- EnableBothScriptContexts();
-}
-
-static void sub_81BEA20(void)
-{
- u8 i;
- u8 spriteId;
-
- for (i = 0; i < 8; i++)
- {
- spriteId = CreateSprite(&gUnknown_08617E60, gUnknown_08617D64[i][0] + 120, gUnknown_08617D64[i][1], 8);
- gSprites[spriteId].oam.priority = 0;
- gSprites[spriteId].oam.paletteNum = 0;
- gSprites[spriteId].data[0] = i;
- }
- for (i = 0; i < 8; i++)
- {
- spriteId = CreateSprite(&gUnknown_08617E34, gUnknown_08617D64[i][0] + 115, gUnknown_08617D64[i][1] - 3, 8);
- gSprites[spriteId].oam.priority = 0;
- gSprites[spriteId].oam.paletteNum = 0;
- gSprites[spriteId].data[0] = i;
- }
-}
-
-static void sub_81BEAD8(struct Sprite* sprite)
-{
- sprite->data[1] += 2;
- sprite->pos2.y = (sprite->data[1] / 2);
- if (((sprite->pos1.y) + (sprite->pos2.y)) > gUnknown_08617D64[sprite->data[0]][2])
- {
- DestroySprite(sprite);
- sub_81BE968();
- }
-}
diff --git a/src/fldeff_sweetscent.c b/src/fldeff_sweetscent.c
index 2363e8162..a187353ff 100644
--- a/src/fldeff_sweetscent.c
+++ b/src/fldeff_sweetscent.c
@@ -6,6 +6,7 @@
#include "field_screen_effect.h"
#include "field_weather.h"
#include "fldeff.h"
+#include "mirage_tower.h"
#include "palette.h"
#include "party_menu.h"
#include "script.h"
@@ -63,7 +64,7 @@ static void TrySweetScentEncounter(u8 taskId)
{
if (!gPaletteFade.active)
{
- sub_81BE72C();
+ ClearMirageTowerPulseBlendEffect();
BlendPalettes(0x00000040, 8, RGB_RED);
if (gTasks[taskId].data[0] == 64)
{
@@ -76,7 +77,7 @@ static void TrySweetScentEncounter(u8 taskId)
{
gTasks[taskId].func = FailSweetScentEncounter;
BeginNormalPaletteFade(~(1 << (gSprites[GetPlayerAvatarObjectId()].oam.paletteNum + 16)), 4, 8, 0, RGB_RED);
- sub_81BE6B8();
+ TryStartMirageTowerPulseBlendEffect();
}
}
else
diff --git a/src/fossil_specials.c b/src/fossil_specials.c
deleted file mode 100644
index dfdb999a9..000000000
--- a/src/fossil_specials.c
+++ /dev/null
@@ -1,561 +0,0 @@
-#include "global.h"
-#include "constants/flags.h"
-#include "constants/songs.h"
-#include "bg.h"
-#include "event_data.h"
-#include "field_camera.h"
-#include "event_object_movement.h"
-#include "fieldmap.h"
-#include "global.fieldmap.h"
-#include "gpu_regs.h"
-#include "alloc.h"
-#include "menu.h"
-#include "random.h"
-#include "script.h"
-#include "sound.h"
-#include "sprite.h"
-#include "task.h"
-#include "window.h"
-
-#define MIRAGE_TOWER_GFX_LENGTH (32 + sizeof(gMirageTower_Gfx))
-#define MIRAGE_TOWER_PALETTE_LENGTH 0x800
-#define ROOT_FOSSIL_GFX_LENGTH sizeof(gRootFossil_Gfx)
-#define ROOT_FOSSIL_GFX_RANDOMIZER_LENGTH 0x100
-
-struct Struct8617DA4
-{
- u8 x;
- u8 y;
- u16 tileId;
-};
-
-struct Struct203CF10
-{
- u8 *buffer;
- u8 currIndex;
-};
-
-struct DynamicSpriteFrameImage
-{
- u8 *data;
- u16 size;
-};
-
-struct Struct203CF0C
-{
- u8 *frameImageTiles;
- struct DynamicSpriteFrameImage *frameImage;
- u8 spriteId;
- u16 *unkC;
- u16 unk10;
-};
-
-// static functions
-static void sub_81BED50(u8 taskId);
-static void sub_81BEBF4(u8 taskId);
-static void sub_81BF028(u8 taskId);
-static void sub_81BF248(struct Sprite *);
-static void sub_81BF2B8(u8* a, u16 b, u8 c, u8 d, u8 e);
-
-// .rodata
-static const u8 gUnknown_08617274[32] = {0};
-static const u8 gMirageTower_Gfx[] = INCBIN_U8("graphics/misc/mirage_tower.4bpp");
-static const u16 gUnknown_08617B94[] = INCBIN_U16("graphics/misc/mirage_tower.bin");
-static const u16 gRootFossil_Pal[] = INCBIN_U16("graphics/misc/fossil.gbapal");
-static const u8 gRootFossil_Gfx[] = INCBIN_U8("graphics/misc/fossil.4bpp");
-static const u8 gMirageTowerCrumbles_Gfx[] = INCBIN_U8("graphics/misc/mirage_tower_crumbles.4bpp");
-static const u16 gMirageTowerCrumbles_Palette[] = INCBIN_U16("graphics/misc/mirage_tower_crumbles.gbapal");
-
-const s16 gUnknown_08617D64[][3] =
-{
- { 0, 10, 65},
- { 17, 3, 50},
- {-12, 0, 75},
- { 10, 15, 90},
- { 7, 8, 65},
- {-18, 5, 75},
- { 22, -10, 55},
- {-24, -4, 65},
-};
-
-const struct SpriteSheet gUnknown_08617D94[] =
-{
- {gMirageTowerCrumbles_Gfx, 0x0080, 0x0fa0},
- {NULL}
-};
-
-static const struct Struct8617DA4 gUnknown_08617DA4[] =
-{
- {0x12, 0x35, 0x251},
- {0x13, 0x35, 0x251},
- {0x14, 0x35, 0x251},
- {0x12, 0x36, 0x251},
- {0x13, 0x36, 0x251},
- {0x14, 0x36, 0x251},
- {0x12, 0x37, 0x251},
- {0x13, 0x37, 0x251},
- {0x14, 0x37, 0x251},
- {0x12, 0x38, 0x251},
- {0x13, 0x38, 0x251},
- {0x14, 0x38, 0x251},
- {0x12, 0x39, 0x259},
- {0x13, 0x39, 0x259},
- {0x14, 0x39, 0x259},
- {0x12, 0x3A, 0x121},
- {0x13, 0x3A, 0x121},
- {0x14, 0x3A, 0x121},
-};
-
-static const union AnimCmd gSpriteAnim_8617DEC[] =
-{
- ANIMCMD_FRAME(0, 1),
- ANIMCMD_END,
-};
-
-static const struct OamData gOamData_8617DF4 =
-{
- .y = 0,
- .affineMode = 0,
- .objMode = 0,
- .mosaic = 0,
- .bpp = 0,
- .shape = 0,
- .x = 0,
- .matrixNum = 0,
- .size = 1,
- .tileNum = 0,
- .priority = 0,
- .paletteNum = 3,
- .affineParam = 0,
-};
-
-static const union AnimCmd *const gSpriteAnimTable_8617DFC[] =
-{
- gSpriteAnim_8617DEC,
-};
-
-static const struct SpriteTemplate gUnknown_08617E00 =
-{
- 0xFFFF, 0xFFFF, &gOamData_8617DF4, gSpriteAnimTable_8617DFC, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy
-};
-
-// EWRAM
-EWRAM_DATA static u8* sUnknown_0203CF04 = NULL;
-EWRAM_DATA static u8* sUnknown_0203CF08 = NULL;
-EWRAM_DATA static struct Struct203CF0C *sUnknown_0203CF0C = NULL;
-EWRAM_DATA static struct Struct203CF10 *sUnknown_0203CF10 = NULL;
-EWRAM_DATA static u16 *sUnknown_0203CF14 = NULL;
-
-// IWRAM bss
-IWRAM_DATA static u16 gUnknown_030012A8[8];
-
-// text
-void sub_81BEB24(void)
-{
- u8 i;
- for (i = 0; i < (sizeof(gUnknown_08617DA4)/sizeof(gUnknown_08617DA4[0])); i++)
- MapGridSetMetatileIdAt(gUnknown_08617DA4[i].x + 7, gUnknown_08617DA4[i].y + 7, gUnknown_08617DA4[i].tileId);
- DrawWholeMapView();
-}
-
-void sub_81BEB54(void)
-{
- CreateTask(sub_81BED50, 9);
-}
-
-void sub_81BEB68(void)
-{
- CreateTask(sub_81BEBF4, 9);
-}
-
-void sub_81BEB7C(void)
-{
- CreateTask(sub_81BF028, 9);
-}
-
-void sub_81BEB90(void)
-{
- SetGpuReg(REG_OFFSET_BG0HOFS, sUnknown_0203CF14[0]);
- SetGpuReg(REG_OFFSET_BG0VOFS, sUnknown_0203CF14[1]);
-}
-
-void sub_81BEBB4(u8 taskId)
-{
- if (!(gTasks[taskId].data[0]))
- {
- sUnknown_0203CF14[0] = -sUnknown_0203CF14[0];
- gTasks[taskId].data[0] = 2;
- sub_81BEB90();
- }
- else
- {
- gTasks[taskId].data[0]--;
- }
-}
-
-static void sub_81BEBF4(u8 taskId)
-{
- u8 zero;
-
- switch (gTasks[taskId].data[0])
- {
- case 0:
- FreeAllWindowBuffers();
- SetBgAttribute(0, BG_CTRL_ATTR_MOSAIC, 2);
- gTasks[taskId].data[0]++;
- break;
- case 1:
- sUnknown_0203CF04 = (u8 *)AllocZeroed(MIRAGE_TOWER_GFX_LENGTH);
- sUnknown_0203CF08 = (u8 *)AllocZeroed(MIRAGE_TOWER_PALETTE_LENGTH);
- ChangeBgX(0, 0, 0);
- ChangeBgY(0, 0, 0);
- gTasks[taskId].data[0]++;
- break;
- case 2:
- CpuSet(gUnknown_08617274, sUnknown_0203CF04, MIRAGE_TOWER_GFX_LENGTH / 2);
- LoadBgTiles(0, sUnknown_0203CF04, MIRAGE_TOWER_GFX_LENGTH, 0);
- gTasks[taskId].data[0]++;
- break;
- case 3:
- SetBgTilemapBuffer(0, sUnknown_0203CF08);
- CopyToBgTilemapBufferRect_ChangePalette(0, &gUnknown_08617B94, 12, 29, 6, 12, 17);
- CopyBgTilemapBufferToVram(0);
- gTasks[taskId].data[0]++;
- break;
- case 4:
- ShowBg(0);
- gTasks[taskId].data[0]++;
- break;
- case 5:
- sub_81BEB24();
- gTasks[taskId].data[0]++;
- break;
- case 6:
- sUnknown_0203CF14 = Alloc(4);
- zero = 0;
- sUnknown_0203CF14[0] = 2;
- sUnknown_0203CF14[1] = zero;
- CreateTask(sub_81BEBB4, 0xA);
- DestroyTask(taskId);
- EnableBothScriptContexts();
- break;
- }
-}
-
-#define OUTER_BUFFER_LENGTH 0x60
-#define INNER_BUFFER_LENGTH 0x30
-static void sub_81BED50(u8 taskId)
-{
- u8 anotherTaskId, j;
- u16 i;
- u8 index;
-
- switch (gTasks[taskId].data[0])
- {
- case 1:
- sUnknown_0203CF10 = AllocZeroed(OUTER_BUFFER_LENGTH * sizeof(struct Struct203CF10));
- break;
- case 3:
- if (gTasks[taskId].data[3] <= (OUTER_BUFFER_LENGTH - 1))
- {
- if (gTasks[taskId].data[1] > 1)
- {
- index = gTasks[taskId].data[3];
- sUnknown_0203CF10[index].buffer = Alloc(INNER_BUFFER_LENGTH);
- for (i = 0; i <= (INNER_BUFFER_LENGTH - 1); i++)
- sUnknown_0203CF10[index].buffer[i] = i;
- for (i = 0; i <= (INNER_BUFFER_LENGTH - 1); i++)
- {
- u16 rand1, rand2, temp;
-
- rand1 = Random() % 0x30;
- rand2 = Random() % 0x30;
- SWAP(sUnknown_0203CF10[index].buffer[rand2], sUnknown_0203CF10[index].buffer[rand1], temp);
- }
- if (gTasks[taskId].data[3] <= (OUTER_BUFFER_LENGTH - 1))
- gTasks[taskId].data[3]++;
- gTasks[taskId].data[1] = 0;
- }
- gTasks[taskId].data[1]++;
- }
- index = gTasks[taskId].data[3];
- for (i = (u8)(gTasks[taskId].data[2]); i < index; i++)
- {
- for (j = 0; j < 1; j++)
- {
- sub_81BF2B8(sUnknown_0203CF04,
- ((((OUTER_BUFFER_LENGTH - 1) - i) * INNER_BUFFER_LENGTH) + sUnknown_0203CF10[i].buffer[(sUnknown_0203CF10[i].currIndex)++]),
- 0, INNER_BUFFER_LENGTH, 1);
- }
- if (sUnknown_0203CF10[i].currIndex > (INNER_BUFFER_LENGTH - 1))
- {
- FREE_AND_SET_NULL(sUnknown_0203CF10[i].buffer);
- gTasks[taskId].data[2]++;
- if ((i % 2) == 1)
- sUnknown_0203CF14[1]--;
- }
- }
- LoadBgTiles(0, sUnknown_0203CF04, MIRAGE_TOWER_GFX_LENGTH, 0);
- if (sUnknown_0203CF10[OUTER_BUFFER_LENGTH - 1].currIndex > (INNER_BUFFER_LENGTH - 1))
- break;
- return;
- case 4:
- UnsetBgTilemapBuffer(0);
- anotherTaskId = FindTaskIdByFunc(sub_81BEBB4);
- if (anotherTaskId != 0xFF)
- DestroyTask(anotherTaskId);
- sUnknown_0203CF14[1] = sUnknown_0203CF14[0] = 0;
- sub_81BEB90();
- break;
- case 5:
- FREE_AND_SET_NULL(sUnknown_0203CF14);
- FREE_AND_SET_NULL(sUnknown_0203CF10);
- FREE_AND_SET_NULL(sUnknown_0203CF04);
- FREE_AND_SET_NULL(sUnknown_0203CF08);
- break;
- case 6:
- SetGpuRegBits(REG_OFFSET_BG2CNT, 0x2);
- SetGpuRegBits(REG_OFFSET_BG0CNT, 0x0);
- SetBgAttribute(0, BG_CTRL_ATTR_MOSAIC, 0);
- sub_81971D0();
- break;
- case 7:
- ShowBg(0);
- break;
- case 8:
- DestroyTask(taskId);
- EnableBothScriptContexts();
- break;
- }
- gTasks[taskId].data[0]++;
-}
-
-static void sub_81BF028(u8 taskId)
-{
- u16 i;
- u8 *buffer;
-
- switch (gTasks[taskId].data[0])
- {
- case 1:
- sUnknown_0203CF0C = AllocZeroed(sizeof(*sUnknown_0203CF0C));
- sUnknown_0203CF0C->frameImageTiles = AllocZeroed(ROOT_FOSSIL_GFX_LENGTH);
- sUnknown_0203CF0C->frameImage = AllocZeroed(sizeof(*sUnknown_0203CF0C->frameImage));
- sUnknown_0203CF0C->unkC = AllocZeroed(ROOT_FOSSIL_GFX_RANDOMIZER_LENGTH * sizeof(u16));
- sUnknown_0203CF0C->unk10 = 0;
- break;
- case 2:
- buffer = sUnknown_0203CF0C->frameImageTiles;
- for (i = 0; i < ROOT_FOSSIL_GFX_LENGTH; i++, buffer++)
- *buffer = gRootFossil_Gfx[i];
- break;
- case 3:
- sUnknown_0203CF0C->frameImage->data = sUnknown_0203CF0C->frameImageTiles;
- sUnknown_0203CF0C->frameImage->size = ROOT_FOSSIL_GFX_LENGTH;
- break;
- case 4:
- {
- struct SpriteTemplate fossilTemplate;
-
- fossilTemplate = gUnknown_08617E00;
- fossilTemplate.images = (struct SpriteFrameImage *)(sUnknown_0203CF0C->frameImage);
- sUnknown_0203CF0C->spriteId = CreateSprite(&fossilTemplate, 128, -16, 1);
- gSprites[sUnknown_0203CF0C->spriteId].centerToCornerVecX = 0;
- gSprites[sUnknown_0203CF0C->spriteId].data[0] = gSprites[sUnknown_0203CF0C->spriteId].pos1.x;
- gSprites[sUnknown_0203CF0C->spriteId].data[1] = 1;
- }
- case 5:
- for (i = 0; i < ROOT_FOSSIL_GFX_RANDOMIZER_LENGTH; i++)
- sUnknown_0203CF0C->unkC[i] = i;
- break;
- case 6:
- for (i = 0; i < (ROOT_FOSSIL_GFX_RANDOMIZER_LENGTH * sizeof(u16)); i++)
- {
- u16 rand1, rand2, temp;
-
- rand1 = Random() % 0x100;
- rand2 = Random() % 0x100;
- SWAP(sUnknown_0203CF0C->unkC[rand2], sUnknown_0203CF0C->unkC[rand1], temp);
- }
- gSprites[sUnknown_0203CF0C->spriteId].callback = sub_81BF248;
- break;
- case 7:
- if (gSprites[sUnknown_0203CF0C->spriteId].callback != SpriteCallbackDummy)
- return;
- DestroySprite(&gSprites[sUnknown_0203CF0C->spriteId]);
- FREE_AND_SET_NULL(sUnknown_0203CF0C->unkC);;
- FREE_AND_SET_NULL(sUnknown_0203CF0C->frameImage);
- FREE_AND_SET_NULL(sUnknown_0203CF0C->frameImageTiles);
- FREE_AND_SET_NULL(sUnknown_0203CF0C);
- break;
- case 8:
- EnableBothScriptContexts();
- break;
- }
-
- gTasks[taskId].data[0]++;
-}
-
-static void sub_81BF248(struct Sprite *sprite)
-{
- if (sUnknown_0203CF0C->unk10 >= (ROOT_FOSSIL_GFX_RANDOMIZER_LENGTH))
- {
- sprite->callback = SpriteCallbackDummy;
- }
- else if (sprite->pos1.y >= 0x60)
- {
- u8 i;
- for (i = 0; i < 2; i++)
- {
- sub_81BF2B8(sUnknown_0203CF0C->frameImageTiles, sUnknown_0203CF0C->unkC[sUnknown_0203CF0C->unk10++], 0, 16, 0);
- }
- StartSpriteAnim(sprite, 0);
- }
- else
- {
- sprite->pos1.y++;
- }
-}
-
-#ifdef NONMATCHING
-static void sub_81BF2B8(u8* a, u16 b, u8 c, u8 d, u8 e)
-{
- u8 r5, r4, r0, r2;
- u16 var;
-
- r4 = r5 = b / d;
- gUnknown_030012A8[0] = r4;
-
- r0 = r2 = b % d;
- gUnknown_030012A8[1] = r2;
-
- r4 &= 7;
- r2 &= 7;
- gUnknown_030012A8[2] = r4;
- gUnknown_030012A8[3] = r2;
-
- r0 /= 8;
- r5 /= 8;
- gUnknown_030012A8[4] = r0;
- gUnknown_030012A8[5] = r5;
-
- var = ((d / 8) * (r5 * 64)) + (r0 * 64);
- gUnknown_030012A8[6] = var;
-
- var += (r4 * 8) + r2;
- gUnknown_030012A8[7] = var;
-
- // This part is non-matching. 99% sure it IS functionally equivalent, though.
- b = (b & 1) ^ 1;
- c = (c << ((b) << 2)) | (15 << ((b ^ 1) << 2));
-
- a[(var / 2) + (e * 32)] &= c;
-}
-
-#else
-NAKED
-static void sub_81BF2B8(u8* a, u16 b, u8 c, u8 d, u8 e)
-{
- asm_unified("\n\
- push {r4-r7,lr}\n\
- mov r7, r10\n\
- mov r6, r9\n\
- mov r5, r8\n\
- push {r5-r7}\n\
- sub sp, 0x8\n\
- str r0, [sp]\n\
- mov r10, r1\n\
- adds r6, r2, 0\n\
- mov r8, r3\n\
- ldr r0, [sp, 0x28]\n\
- mov r9, r0\n\
- lsls r1, 16\n\
- lsrs r1, 16\n\
- mov r10, r1\n\
- lsls r6, 24\n\
- lsrs r6, 24\n\
- mov r0, r8\n\
- lsls r0, 24\n\
- mov r8, r0\n\
- lsrs r7, r0, 24\n\
- mov r1, r9\n\
- lsls r1, 24\n\
- lsrs r1, 24\n\
- mov r9, r1\n\
- mov r0, r10\n\
- adds r1, r7, 0\n\
- bl __divsi3\n\
- adds r5, r0, 0\n\
- lsls r5, 24\n\
- lsrs r4, r5, 24\n\
- ldr r3, =gUnknown_030012A8\n\
- strh r4, [r3]\n\
- mov r0, r10\n\
- adds r1, r7, 0\n\
- str r3, [sp, 0x4]\n\
- bl __modsi3\n\
- lsls r0, 24\n\
- lsrs r2, r0, 24\n\
- ldr r3, [sp, 0x4]\n\
- strh r2, [r3, 0x2]\n\
- movs r1, 0x7\n\
- ands r4, r1\n\
- ands r2, r1\n\
- strh r4, [r3, 0x4]\n\
- strh r2, [r3, 0x6]\n\
- lsrs r0, 27\n\
- lsrs r5, 27\n\
- strh r0, [r3, 0x8]\n\
- strh r5, [r3, 0xA]\n\
- mov r1, r8\n\
- lsrs r1, 27\n\
- lsls r1, 6\n\
- mov r8, r1\n\
- mov r1, r8\n\
- muls r1, r5\n\
- lsls r0, 6\n\
- adds r1, r0\n\
- lsls r1, 16\n\
- lsrs r1, 16\n\
- strh r1, [r3, 0xC]\n\
- lsls r4, 3\n\
- adds r4, r2\n\
- adds r1, r4\n\
- lsls r4, r1, 16\n\
- lsrs r4, 17\n\
- strh r1, [r3, 0xE]\n\
- movs r1, 0x1\n\
- mov r0, r10\n\
- ands r1, r0\n\
- movs r2, 0x1\n\
- eors r1, r2\n\
- lsls r0, r1, 2\n\
- lsls r6, r0\n\
- eors r1, r2\n\
- lsls r1, 2\n\
- movs r0, 0xF\n\
- lsls r0, r1\n\
- orrs r6, r0\n\
- lsls r6, 24\n\
- lsrs r6, 24\n\
- mov r1, r9\n\
- lsls r1, 5\n\
- mov r9, r1\n\
- add r9, r4\n\
- ldr r1, [sp]\n\
- add r1, r9\n\
- ldrb r0, [r1]\n\
- ands r6, r0\n\
- strb r6, [r1]\n\
- add sp, 0x8\n\
- pop {r3-r5}\n\
- mov r8, r3\n\
- mov r9, r4\n\
- mov r10, r5\n\
- pop {r4-r7}\n\
- pop {r0}\n\
- bx r0\n\
- .pool\n\
- ");
-}
-#endif // NONMATCHING
diff --git a/src/mirage_tower.c b/src/mirage_tower.c
new file mode 100644
index 000000000..d002e1de4
--- /dev/null
+++ b/src/mirage_tower.c
@@ -0,0 +1,868 @@
+#include "global.h"
+#include "alloc.h"
+#include "bg.h"
+#include "event_data.h"
+#include "event_object_movement.h"
+#include "field_camera.h"
+#include "fieldmap.h"
+#include "gpu_regs.h"
+#include "menu.h"
+#include "random.h"
+#include "roulette_util.h"
+#include "script.h"
+#include "sound.h"
+#include "sprite.h"
+#include "task.h"
+#include "window.h"
+#include "constants/flags.h"
+#include "constants/maps.h"
+#include "constants/rgb.h"
+#include "constants/songs.h"
+
+struct MirageTowerPulseBlend {
+ u8 taskId;
+ struct PulseBlend pulseBlend;
+};
+
+struct MetatileCoords
+{
+ u8 x;
+ u8 y;
+ u16 metatileId;
+};
+
+struct BgRegOffsets
+{
+ u16 bgHOFS;
+ u16 bgVOFS;
+};
+
+struct Struct203CF10
+{
+ u8 *buffer;
+ u8 currIndex;
+};
+
+struct DynamicSpriteFrameImage
+{
+ u8 *data;
+ u16 size;
+};
+
+struct Struct203CF0C
+{
+ u8 *frameImageTiles;
+ struct DynamicSpriteFrameImage *frameImage;
+ u8 spriteId;
+ u16 *unkC;
+ u16 unk10;
+};
+
+#define MIRAGE_TOWER_GFX_LENGTH (sizeof(sBlankTile_Gfx) + sizeof(sMirageTower_Gfx))
+#define ROOT_FOSSIL_GFX_LENGTH sizeof(sRootFossil_Gfx)
+#define ROOT_FOSSIL_GFX_RANDOMIZER_LENGTH 0x100
+
+// extern data
+extern const struct SpriteSheet gMirageTowerCeilingCrumbleSpriteSheets[];
+extern const s16 sCeilingCrumblePositions[][3];
+
+// static functions
+static void PlayerDescendMirageTower(u8 taskId);
+static void DoScreenShake(u8 taskId);
+static void IncrementCeilingCrumbleFinishedCount(void);
+static void WaitCeilingCrumble(u8 taskId);
+static void FinishCeilingCrumbleTask(u8 taskId);
+static void CreateCeilingCrumbleSprites(void);
+static void MoveCeilingCrumbleSprite(struct Sprite* sprite);
+static void DoMirageTowerDisintegration(u8 taskId);
+static void InitMirageTowerShake(u8 taskId);
+static void DoFossilFallAndSink(u8 taskId);
+static void sub_81BF248(struct Sprite *);
+static void sub_81BF2B8(u8* a, u16 b, u8 c, u8 d, u8 e);
+
+// rodata
+static const u8 sBlankTile_Gfx[32] = {0};
+static const u8 sMirageTower_Gfx[] = INCBIN_U8("graphics/misc/mirage_tower.4bpp");
+static const u16 sMirageTowerTilemap[] = INCBIN_U16("graphics/misc/mirage_tower.bin");
+static const u16 sRootFossil_Pal[] = INCBIN_U16("graphics/misc/fossil.gbapal");
+static const u8 sRootFossil_Gfx[] = INCBIN_U8("graphics/misc/fossil.4bpp");
+static const u8 sMirageTowerCrumbles_Gfx[] = INCBIN_U8("graphics/misc/mirage_tower_crumbles.4bpp");
+static const u16 sMirageTowerCrumbles_Palette[] = INCBIN_U16("graphics/misc/mirage_tower_crumbles.gbapal");
+
+const s16 sCeilingCrumblePositions[][3] =
+{
+ { 0, 10, 65},
+ { 17, 3, 50},
+ {-12, 0, 75},
+ { 10, 15, 90},
+ { 7, 8, 65},
+ {-18, 5, 75},
+ { 22, -10, 55},
+ {-24, -4, 65},
+};
+
+const struct SpriteSheet gMirageTowerCeilingCrumbleSpriteSheets[] =
+{
+ {sMirageTowerCrumbles_Gfx, 0x0080, 4000},
+ {NULL}
+};
+
+static const struct MetatileCoords sInvisibleMirageTowerMetatiles[] =
+{
+ {18, 53, 0x251},
+ {19, 53, 0x251},
+ {20, 53, 0x251},
+ {18, 54, 0x251},
+ {19, 54, 0x251},
+ {20, 54, 0x251},
+ {18, 55, 0x251},
+ {19, 55, 0x251},
+ {20, 55, 0x251},
+ {18, 56, 0x251},
+ {19, 56, 0x251},
+ {20, 56, 0x251},
+ {18, 57, 0x259},
+ {19, 57, 0x259},
+ {20, 57, 0x259},
+ {18, 58, 0x121},
+ {19, 58, 0x121},
+ {20, 58, 0x121},
+};
+
+static const union AnimCmd gSpriteAnim_8617DEC[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END,
+};
+
+static const struct OamData gOamData_8617DF4 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 3,
+ .affineParam = 0,
+};
+
+static const union AnimCmd *const gSpriteAnimTable_8617DFC[] =
+{
+ gSpriteAnim_8617DEC,
+};
+
+static const struct SpriteTemplate gUnknown_08617E00 =
+{
+ 0xFFFF, 0xFFFF, &gOamData_8617DF4, gSpriteAnimTable_8617DFC, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy
+};
+
+const struct PulseBlendSettings gMirageTowerPulseBlendSettings = {
+ .blendColor = RGB(27, 25, 16),
+ .paletteOffset = 0x61,
+ .numColors = 15,
+ .delay = 5,
+ .numFadeCycles = -1,
+ .maxBlendCoeff = 11,
+ .fadeType = 1,
+ .restorePaletteOnUnload = FALSE,
+ .unk7_7 = 1,
+};
+
+static const union AnimCmd sCeilingCrumble2AnimCmd[] =
+{
+ ANIMCMD_FRAME(0, 12),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const sCeilingCrumble2AnimCmds[] =
+{
+ sCeilingCrumble2AnimCmd,
+};
+
+static const struct OamData sCeilingCrumble2OamData =
+{
+ .y = 0,
+ .affineMode = ST_OAM_AFFINE_OFF,
+ .objMode = ST_OAM_OBJ_NORMAL,
+ .mosaic = 0,
+ .bpp = ST_OAM_4BPP,
+ .shape = ST_OAM_SQUARE,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 0,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const struct SpriteTemplate sCeilingCrumbleSpriteTemplate2 = {
+ .tileTag = 4000,
+ .paletteTag = 0xFFFF,
+ .oam = &sCeilingCrumble2OamData,
+ .anims = sCeilingCrumble2AnimCmds,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = MoveCeilingCrumbleSprite
+};
+
+static const union AnimCmd sCeilingCrumble1AnimCmd[] =
+{
+ ANIMCMD_FRAME(0, 12),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const sCeilingCrumble1AnimCmds[] =
+{
+ sCeilingCrumble1AnimCmd,
+};
+
+static const struct OamData sCeilingCrumble1OamData =
+{
+ .y = 0,
+ .affineMode = ST_OAM_AFFINE_OFF,
+ .objMode = ST_OAM_OBJ_NORMAL,
+ .mosaic = 0,
+ .bpp = ST_OAM_4BPP,
+ .shape = ST_OAM_SQUARE,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const struct SpriteTemplate sCeilingCrumbleSpriteTemplate1 = {
+ .tileTag = 4000,
+ .paletteTag = 0xFFFF,
+ .oam = &sCeilingCrumble1OamData,
+ .anims = sCeilingCrumble1AnimCmds,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = MoveCeilingCrumbleSprite
+};
+
+EWRAM_DATA static u8* sMirageTowerGfxBuffer = NULL;
+EWRAM_DATA static u8* sMirageTowerTilemapBuffer = NULL;
+EWRAM_DATA static struct Struct203CF0C *sUnknown_0203CF0C = NULL;
+EWRAM_DATA static struct Struct203CF10 *sUnknown_0203CF10 = NULL;
+EWRAM_DATA static struct BgRegOffsets *sBgShakeOffsets = NULL;
+EWRAM_DATA struct MirageTowerPulseBlend *sMirageTowerPulseBlend = NULL;
+
+IWRAM_DATA static u16 gUnknown_030012A8[8];
+
+bool8 IsMirageTowerVisible(void)
+{
+ if (!(gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(ROUTE111) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE111)))
+ return FALSE;
+ return FlagGet(FLAG_MIRAGE_TOWER_VISIBLE);
+}
+
+static void UpdateMirageTowerPulseBlend(u8 taskId)
+{
+ UpdatePulseBlend(&sMirageTowerPulseBlend->pulseBlend);
+}
+
+void ClearMirageTowerPulseBlend(void)
+{
+ sMirageTowerPulseBlend = NULL;
+}
+
+void TryStartMirageTowerPulseBlendEffect(void)
+{
+ if (sMirageTowerPulseBlend)
+ {
+ sMirageTowerPulseBlend = NULL;
+ return;
+ }
+
+ if (gSaveBlock1Ptr->location.mapGroup != MAP_GROUP(ROUTE111)
+ || gSaveBlock1Ptr->location.mapNum != MAP_NUM(ROUTE111)
+ || !FlagGet(FLAG_MIRAGE_TOWER_VISIBLE))
+ return;
+
+ sMirageTowerPulseBlend = AllocZeroed(sizeof(*sMirageTowerPulseBlend));
+ InitPulseBlend(&sMirageTowerPulseBlend->pulseBlend);
+ InitPulseBlendPaletteSettings(&sMirageTowerPulseBlend->pulseBlend, &gMirageTowerPulseBlendSettings);
+ MarkUsedPulseBlendPalettes(&sMirageTowerPulseBlend->pulseBlend, 0x1, TRUE);
+ sMirageTowerPulseBlend->taskId = CreateTask(UpdateMirageTowerPulseBlend, 0xFF);
+}
+
+void ClearMirageTowerPulseBlendEffect(void)
+{
+ if (gSaveBlock1Ptr->location.mapGroup != MAP_GROUP(ROUTE111)
+ || gSaveBlock1Ptr->location.mapNum != MAP_NUM(ROUTE111)
+ || !FlagGet(FLAG_MIRAGE_TOWER_VISIBLE)
+ || sMirageTowerPulseBlend == NULL)
+ return;
+
+ if (FuncIsActiveTask(UpdateMirageTowerPulseBlend))
+ DestroyTask(sMirageTowerPulseBlend->taskId);
+
+ UnmarkUsedPulseBlendPalettes(&sMirageTowerPulseBlend->pulseBlend, 0x1, TRUE);
+ UnloadUsedPulseBlendPalettes(&sMirageTowerPulseBlend->pulseBlend, 0x1, TRUE);
+ FREE_AND_SET_NULL(sMirageTowerPulseBlend);
+}
+
+void SetMirageTowerVisibility(void)
+{
+ u16 rand;
+ bool8 visible;
+
+ if (VarGet(VAR_0x40CB))
+ {
+ FlagClear(FLAG_MIRAGE_TOWER_VISIBLE);
+ return;
+ }
+
+ rand = Random();
+ visible = rand & 1;
+ if (FlagGet(FLAG_FORCE_MIRAGE_TOWER_VISIBLE) == TRUE)
+ visible = TRUE;
+
+ if (visible)
+ {
+ FlagSet(FLAG_MIRAGE_TOWER_VISIBLE);
+ TryStartMirageTowerPulseBlendEffect();
+ return;
+ }
+
+ FlagClear(FLAG_MIRAGE_TOWER_VISIBLE);
+}
+
+void StartPlayerDescendMirageTower(void)
+{
+ CreateTask(PlayerDescendMirageTower, 8);
+}
+
+static void PlayerDescendMirageTower(u8 taskId)
+{
+ u8 eventObjectId;
+ struct EventObject *fakePlayerEventObject;
+ struct EventObject *playerEventObject;
+
+ TryGetEventObjectIdByLocalIdAndMap(45, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &eventObjectId);
+ fakePlayerEventObject = &gEventObjects[eventObjectId];
+ gSprites[fakePlayerEventObject->spriteId].pos2.y += 4;
+ playerEventObject = &gEventObjects[gPlayerAvatar.eventObjectId];
+ if ((gSprites[fakePlayerEventObject->spriteId].pos1.y + gSprites[fakePlayerEventObject->spriteId].pos2.y) >=
+ (gSprites[playerEventObject->spriteId].pos1.y + gSprites[playerEventObject->spriteId].pos2.y))
+ {
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ }
+}
+
+static void StartScreenShake(u8 yShakeOffset, u8 xShakeOffset, u8 numShakes, u8 shakeDelay)
+{
+ u8 taskId = CreateTask(DoScreenShake, 9);
+ gTasks[taskId].data[0] = xShakeOffset;
+ gTasks[taskId].data[1] = 0;
+ gTasks[taskId].data[2] = numShakes;
+ gTasks[taskId].data[3] = shakeDelay;
+ gTasks[taskId].data[4] = yShakeOffset;
+ SetCameraPanningCallback(NULL);
+ PlaySE(SE_W070);
+}
+
+static void DoScreenShake(u8 taskId)
+{
+ s16 *data;
+
+ data = gTasks[taskId].data;
+ data[1]++;
+ if (data[1] % data[3] == 0)
+ {
+ data[1] = 0;
+ data[2]--;
+ data[0] = -data[0];
+ data[4] = -data[4];
+ SetCameraPanning(data[0], data[4]);
+ if (data[2] == 0)
+ {
+ IncrementCeilingCrumbleFinishedCount();
+ DestroyTask(taskId);
+ InstallCameraPanAheadCallback();
+ }
+ }
+}
+
+static void IncrementCeilingCrumbleFinishedCount(void)
+{
+ u8 taskId = FindTaskIdByFunc(WaitCeilingCrumble);
+ if (taskId != 0xFF)
+ gTasks[taskId].data[0]++;
+}
+
+void DoMirageTowerCeilingCrumble(void)
+{
+ LoadSpriteSheets(gMirageTowerCeilingCrumbleSpriteSheets);
+ CreateCeilingCrumbleSprites();
+ CreateTask(WaitCeilingCrumble, 8);
+ StartScreenShake(2, 1, 16, 3);
+}
+
+static void WaitCeilingCrumble(u8 taskId)
+{
+ u16 *data = gTasks[taskId].data;
+ data[1]++;
+ // Either wait 1000 frames, or until all 16 crumble sprites and the one screen-shake task are completed.
+ if (data[1] == 1000 || data[0] == 17)
+ gTasks[taskId].func = FinishCeilingCrumbleTask;
+}
+
+static void FinishCeilingCrumbleTask(u8 taskId)
+{
+ FreeSpriteTilesByTag(4000);
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+}
+
+static void CreateCeilingCrumbleSprites(void)
+{
+ u8 i;
+ u8 spriteId;
+
+ for (i = 0; i < 8; i++)
+ {
+ spriteId = CreateSprite(&sCeilingCrumbleSpriteTemplate1, sCeilingCrumblePositions[i][0] + 120, sCeilingCrumblePositions[i][1], 8);
+ gSprites[spriteId].oam.priority = 0;
+ gSprites[spriteId].oam.paletteNum = 0;
+ gSprites[spriteId].data[0] = i;
+ }
+ for (i = 0; i < 8; i++)
+ {
+ spriteId = CreateSprite(&sCeilingCrumbleSpriteTemplate2, sCeilingCrumblePositions[i][0] + 115, sCeilingCrumblePositions[i][1] - 3, 8);
+ gSprites[spriteId].oam.priority = 0;
+ gSprites[spriteId].oam.paletteNum = 0;
+ gSprites[spriteId].data[0] = i;
+ }
+}
+
+static void MoveCeilingCrumbleSprite(struct Sprite* sprite)
+{
+ sprite->data[1] += 2;
+ sprite->pos2.y = sprite->data[1] / 2;
+ if(((sprite->pos1.y) + (sprite->pos2.y)) > sCeilingCrumblePositions[sprite->data[0]][2])
+ {
+ DestroySprite(sprite);
+ IncrementCeilingCrumbleFinishedCount();
+ }
+}
+
+static void SetInvisibleMirageTowerMetatiles(void)
+{
+ u8 i;
+ for (i = 0; i < ARRAY_COUNT(sInvisibleMirageTowerMetatiles); i++)
+ MapGridSetMetatileIdAt(sInvisibleMirageTowerMetatiles[i].x + 7, sInvisibleMirageTowerMetatiles[i].y + 7, sInvisibleMirageTowerMetatiles[i].metatileId);
+ DrawWholeMapView();
+}
+
+void StartMirageTowerDisintegration(void)
+{
+ CreateTask(DoMirageTowerDisintegration, 9);
+}
+
+void StartMirageTowerShake(void)
+{
+ CreateTask(InitMirageTowerShake, 9);
+}
+
+void StartMirageTowerFossilFallAndSink(void)
+{
+ CreateTask(DoFossilFallAndSink, 9);
+}
+
+static void SetBgShakeOffsets(void)
+{
+ SetGpuReg(REG_OFFSET_BG0HOFS, sBgShakeOffsets->bgHOFS);
+ SetGpuReg(REG_OFFSET_BG0VOFS, sBgShakeOffsets->bgVOFS);
+}
+
+static void UpdateBgShake(u8 taskId)
+{
+ if (!gTasks[taskId].data[0])
+ {
+ sBgShakeOffsets->bgHOFS = -sBgShakeOffsets->bgHOFS;
+ gTasks[taskId].data[0] = 2;
+ SetBgShakeOffsets();
+ }
+ else
+ {
+ gTasks[taskId].data[0]--;
+ }
+}
+
+static void InitMirageTowerShake(u8 taskId)
+{
+ u8 zero;
+
+ switch (gTasks[taskId].data[0])
+ {
+ case 0:
+ FreeAllWindowBuffers();
+ SetBgAttribute(0, BG_CTRL_ATTR_MOSAIC, 2);
+ gTasks[taskId].data[0]++;
+ break;
+ case 1:
+ sMirageTowerGfxBuffer = (u8 *)AllocZeroed(MIRAGE_TOWER_GFX_LENGTH);
+ sMirageTowerTilemapBuffer = (u8 *)AllocZeroed(BG_SCREEN_SIZE);
+ ChangeBgX(0, 0, 0);
+ ChangeBgY(0, 0, 0);
+ gTasks[taskId].data[0]++;
+ break;
+ case 2:
+ CpuSet(sBlankTile_Gfx, sMirageTowerGfxBuffer, MIRAGE_TOWER_GFX_LENGTH / 2);
+ LoadBgTiles(0, sMirageTowerGfxBuffer, MIRAGE_TOWER_GFX_LENGTH, 0);
+ gTasks[taskId].data[0]++;
+ break;
+ case 3:
+ SetBgTilemapBuffer(0, sMirageTowerTilemapBuffer);
+ CopyToBgTilemapBufferRect_ChangePalette(0, &sMirageTowerTilemap, 12, 29, 6, 12, 17);
+ CopyBgTilemapBufferToVram(0);
+ gTasks[taskId].data[0]++;
+ break;
+ case 4:
+ ShowBg(0);
+ gTasks[taskId].data[0]++;
+ break;
+ case 5:
+ SetInvisibleMirageTowerMetatiles();
+ gTasks[taskId].data[0]++;
+ break;
+ case 6:
+ sBgShakeOffsets = Alloc(sizeof(*sBgShakeOffsets));
+ zero = 0;
+ sBgShakeOffsets->bgHOFS = 2;
+ sBgShakeOffsets->bgVOFS = zero;
+ CreateTask(UpdateBgShake, 10);
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ break;
+ }
+}
+
+#define OUTER_BUFFER_LENGTH 0x60
+#define INNER_BUFFER_LENGTH 0x30
+static void DoMirageTowerDisintegration(u8 taskId)
+{
+ u8 bgShakeTaskId, j;
+ u16 i;
+ u8 index;
+
+ switch (gTasks[taskId].data[0])
+ {
+ case 1:
+ sUnknown_0203CF10 = AllocZeroed(OUTER_BUFFER_LENGTH * sizeof(struct Struct203CF10));
+ break;
+ case 3:
+ if (gTasks[taskId].data[3] <= (OUTER_BUFFER_LENGTH - 1))
+ {
+ if (gTasks[taskId].data[1] > 1)
+ {
+ index = gTasks[taskId].data[3];
+ sUnknown_0203CF10[index].buffer = Alloc(INNER_BUFFER_LENGTH);
+ for (i = 0; i <= (INNER_BUFFER_LENGTH - 1); i++)
+ sUnknown_0203CF10[index].buffer[i] = i;
+ for (i = 0; i <= (INNER_BUFFER_LENGTH - 1); i++)
+ {
+ u16 rand1, rand2, temp;
+
+ rand1 = Random() % 0x30;
+ rand2 = Random() % 0x30;
+ SWAP(sUnknown_0203CF10[index].buffer[rand2], sUnknown_0203CF10[index].buffer[rand1], temp);
+ }
+ if (gTasks[taskId].data[3] <= (OUTER_BUFFER_LENGTH - 1))
+ gTasks[taskId].data[3]++;
+ gTasks[taskId].data[1] = 0;
+ }
+ gTasks[taskId].data[1]++;
+ }
+ index = gTasks[taskId].data[3];
+ for (i = (u8)(gTasks[taskId].data[2]); i < index; i++)
+ {
+ for (j = 0; j < 1; j++)
+ {
+ sub_81BF2B8(sMirageTowerGfxBuffer,
+ ((((OUTER_BUFFER_LENGTH - 1) - i) * INNER_BUFFER_LENGTH) + sUnknown_0203CF10[i].buffer[(sUnknown_0203CF10[i].currIndex)++]),
+ 0, INNER_BUFFER_LENGTH, 1);
+ }
+ if (sUnknown_0203CF10[i].currIndex > (INNER_BUFFER_LENGTH - 1))
+ {
+ FREE_AND_SET_NULL(sUnknown_0203CF10[i].buffer);
+ gTasks[taskId].data[2]++;
+ if ((i % 2) == 1)
+ sBgShakeOffsets->bgVOFS--;
+ }
+ }
+ LoadBgTiles(0, sMirageTowerGfxBuffer, MIRAGE_TOWER_GFX_LENGTH, 0);
+ if (sUnknown_0203CF10[OUTER_BUFFER_LENGTH - 1].currIndex > (INNER_BUFFER_LENGTH - 1))
+ break;
+ return;
+ case 4:
+ UnsetBgTilemapBuffer(0);
+ bgShakeTaskId = FindTaskIdByFunc(UpdateBgShake);
+ if (bgShakeTaskId != 0xFF)
+ DestroyTask(bgShakeTaskId);
+ sBgShakeOffsets->bgVOFS = sBgShakeOffsets->bgHOFS = 0;
+ SetBgShakeOffsets();
+ break;
+ case 5:
+ FREE_AND_SET_NULL(sBgShakeOffsets);
+ FREE_AND_SET_NULL(sUnknown_0203CF10);
+ FREE_AND_SET_NULL(sMirageTowerGfxBuffer);
+ FREE_AND_SET_NULL(sMirageTowerTilemapBuffer);
+ break;
+ case 6:
+ SetGpuRegBits(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(2));
+ SetGpuRegBits(REG_OFFSET_BG0CNT, BGCNT_PRIORITY(0));
+ SetBgAttribute(0, BG_CTRL_ATTR_MOSAIC, 0);
+ sub_81971D0();
+ break;
+ case 7:
+ ShowBg(0);
+ break;
+ case 8:
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ break;
+ }
+ gTasks[taskId].data[0]++;
+}
+
+static void DoFossilFallAndSink(u8 taskId)
+{
+ u16 i;
+ u8 *buffer;
+
+ switch (gTasks[taskId].data[0])
+ {
+ case 1:
+ sUnknown_0203CF0C = AllocZeroed(sizeof(*sUnknown_0203CF0C));
+ sUnknown_0203CF0C->frameImageTiles = AllocZeroed(ROOT_FOSSIL_GFX_LENGTH);
+ sUnknown_0203CF0C->frameImage = AllocZeroed(sizeof(*sUnknown_0203CF0C->frameImage));
+ sUnknown_0203CF0C->unkC = AllocZeroed(ROOT_FOSSIL_GFX_RANDOMIZER_LENGTH * sizeof(u16));
+ sUnknown_0203CF0C->unk10 = 0;
+ break;
+ case 2:
+ buffer = sUnknown_0203CF0C->frameImageTiles;
+ for (i = 0; i < ROOT_FOSSIL_GFX_LENGTH; i++, buffer++)
+ *buffer = sRootFossil_Gfx[i];
+ break;
+ case 3:
+ sUnknown_0203CF0C->frameImage->data = sUnknown_0203CF0C->frameImageTiles;
+ sUnknown_0203CF0C->frameImage->size = ROOT_FOSSIL_GFX_LENGTH;
+ break;
+ case 4:
+ {
+ struct SpriteTemplate fossilTemplate;
+
+ fossilTemplate = gUnknown_08617E00;
+ fossilTemplate.images = (struct SpriteFrameImage *)(sUnknown_0203CF0C->frameImage);
+ sUnknown_0203CF0C->spriteId = CreateSprite(&fossilTemplate, 128, -16, 1);
+ gSprites[sUnknown_0203CF0C->spriteId].centerToCornerVecX = 0;
+ gSprites[sUnknown_0203CF0C->spriteId].data[0] = gSprites[sUnknown_0203CF0C->spriteId].pos1.x;
+ gSprites[sUnknown_0203CF0C->spriteId].data[1] = 1;
+ }
+ case 5:
+ for (i = 0; i < ROOT_FOSSIL_GFX_RANDOMIZER_LENGTH; i++)
+ sUnknown_0203CF0C->unkC[i] = i;
+ break;
+ case 6:
+ for (i = 0; i < (ROOT_FOSSIL_GFX_RANDOMIZER_LENGTH * sizeof(u16)); i++)
+ {
+ u16 rand1, rand2, temp;
+
+ rand1 = Random() % 0x100;
+ rand2 = Random() % 0x100;
+ SWAP(sUnknown_0203CF0C->unkC[rand2], sUnknown_0203CF0C->unkC[rand1], temp);
+ }
+ gSprites[sUnknown_0203CF0C->spriteId].callback = sub_81BF248;
+ break;
+ case 7:
+ if (gSprites[sUnknown_0203CF0C->spriteId].callback != SpriteCallbackDummy)
+ return;
+ DestroySprite(&gSprites[sUnknown_0203CF0C->spriteId]);
+ FREE_AND_SET_NULL(sUnknown_0203CF0C->unkC);;
+ FREE_AND_SET_NULL(sUnknown_0203CF0C->frameImage);
+ FREE_AND_SET_NULL(sUnknown_0203CF0C->frameImageTiles);
+ FREE_AND_SET_NULL(sUnknown_0203CF0C);
+ break;
+ case 8:
+ EnableBothScriptContexts();
+ break;
+ }
+
+ gTasks[taskId].data[0]++;
+}
+
+static void sub_81BF248(struct Sprite *sprite)
+{
+ if (sUnknown_0203CF0C->unk10 >= (ROOT_FOSSIL_GFX_RANDOMIZER_LENGTH))
+ {
+ sprite->callback = SpriteCallbackDummy;
+ }
+ else if (sprite->pos1.y >= 96)
+ {
+ u8 i;
+ for (i = 0; i < 2; i++)
+ sub_81BF2B8(sUnknown_0203CF0C->frameImageTiles, sUnknown_0203CF0C->unkC[sUnknown_0203CF0C->unk10++], 0, 16, 0);
+
+ StartSpriteAnim(sprite, 0);
+ }
+ else
+ {
+ sprite->pos1.y++;
+ }
+}
+
+#ifdef NONMATCHING
+static void sub_81BF2B8(u8* a, u16 b, u8 c, u8 d, u8 e)
+{
+ u8 r5, r4, r0, r2;
+ u16 var;
+
+ r4 = r5 = b / d;
+ gUnknown_030012A8[0] = r4;
+
+ r0 = r2 = b % d;
+ gUnknown_030012A8[1] = r2;
+
+ r4 &= 7;
+ r2 &= 7;
+ gUnknown_030012A8[2] = r4;
+ gUnknown_030012A8[3] = r2;
+
+ r0 /= 8;
+ r5 /= 8;
+ gUnknown_030012A8[4] = r0;
+ gUnknown_030012A8[5] = r5;
+
+ var = ((d / 8) * (r5 * 64)) + (r0 * 64);
+ gUnknown_030012A8[6] = var;
+
+ var += (r4 * 8) + r2;
+ gUnknown_030012A8[7] = var;
+
+ // This part is non-matching. 99% sure it IS functionally equivalent, though.
+ b = (b & 1) ^ 1;
+ c = (c << ((b) << 2)) | (15 << ((b ^ 1) << 2));
+
+ a[(var / 2) + (e * 32)] &= c;
+}
+
+#else
+NAKED
+static void sub_81BF2B8(u8* a, u16 b, u8 c, u8 d, u8 e)
+{
+ asm_unified("\n\
+ push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ sub sp, 0x8\n\
+ str r0, [sp]\n\
+ mov r10, r1\n\
+ adds r6, r2, 0\n\
+ mov r8, r3\n\
+ ldr r0, [sp, 0x28]\n\
+ mov r9, r0\n\
+ lsls r1, 16\n\
+ lsrs r1, 16\n\
+ mov r10, r1\n\
+ lsls r6, 24\n\
+ lsrs r6, 24\n\
+ mov r0, r8\n\
+ lsls r0, 24\n\
+ mov r8, r0\n\
+ lsrs r7, r0, 24\n\
+ mov r1, r9\n\
+ lsls r1, 24\n\
+ lsrs r1, 24\n\
+ mov r9, r1\n\
+ mov r0, r10\n\
+ adds r1, r7, 0\n\
+ bl __divsi3\n\
+ adds r5, r0, 0\n\
+ lsls r5, 24\n\
+ lsrs r4, r5, 24\n\
+ ldr r3, =gUnknown_030012A8\n\
+ strh r4, [r3]\n\
+ mov r0, r10\n\
+ adds r1, r7, 0\n\
+ str r3, [sp, 0x4]\n\
+ bl __modsi3\n\
+ lsls r0, 24\n\
+ lsrs r2, r0, 24\n\
+ ldr r3, [sp, 0x4]\n\
+ strh r2, [r3, 0x2]\n\
+ movs r1, 0x7\n\
+ ands r4, r1\n\
+ ands r2, r1\n\
+ strh r4, [r3, 0x4]\n\
+ strh r2, [r3, 0x6]\n\
+ lsrs r0, 27\n\
+ lsrs r5, 27\n\
+ strh r0, [r3, 0x8]\n\
+ strh r5, [r3, 0xA]\n\
+ mov r1, r8\n\
+ lsrs r1, 27\n\
+ lsls r1, 6\n\
+ mov r8, r1\n\
+ mov r1, r8\n\
+ muls r1, r5\n\
+ lsls r0, 6\n\
+ adds r1, r0\n\
+ lsls r1, 16\n\
+ lsrs r1, 16\n\
+ strh r1, [r3, 0xC]\n\
+ lsls r4, 3\n\
+ adds r4, r2\n\
+ adds r1, r4\n\
+ lsls r4, r1, 16\n\
+ lsrs r4, 17\n\
+ strh r1, [r3, 0xE]\n\
+ movs r1, 0x1\n\
+ mov r0, r10\n\
+ ands r1, r0\n\
+ movs r2, 0x1\n\
+ eors r1, r2\n\
+ lsls r0, r1, 2\n\
+ lsls r6, r0\n\
+ eors r1, r2\n\
+ lsls r1, 2\n\
+ movs r0, 0xF\n\
+ lsls r0, r1\n\
+ orrs r6, r0\n\
+ lsls r6, 24\n\
+ lsrs r6, 24\n\
+ mov r1, r9\n\
+ lsls r1, 5\n\
+ mov r9, r1\n\
+ add r9, r4\n\
+ ldr r1, [sp]\n\
+ add r1, r9\n\
+ ldrb r0, [r1]\n\
+ ands r6, r0\n\
+ strb r6, [r1]\n\
+ add sp, 0x8\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .pool\n\
+ ");
+}
+#endif // NONMATCHING
diff --git a/src/overworld.c b/src/overworld.c
index 27bd0425a..ea4b44cbf 100644
--- a/src/overworld.c
+++ b/src/overworld.c
@@ -31,6 +31,7 @@
#include "map_name_popup.h"
#include "menu.h"
#include "metatile_behavior.h"
+#include "mirage_tower.h"
#include "money.h"
#include "new_game.h"
#include "palette.h"
@@ -112,7 +113,6 @@ extern void sub_81AA1D8(void);
extern void c2_change_map(void);
extern void sub_81D5DF8(void);
extern void sub_80EB218(void);
-extern void sub_81BE72C(void);
extern void sub_80AF3C8(void);
extern void sub_81971F4(void);
extern void sub_808B578(void);
@@ -134,7 +134,6 @@ extern void sub_81AA2F8(void);
extern void sub_8195E10(void);
extern void sub_80EDB44(void);
extern void sub_81D64C0(void);
-extern void sub_81BE6AC(void);
extern void sub_8098128(void);
extern void copy_map_tileset1_to_vram(const struct MapLayout *);
extern void copy_map_tileset2_to_vram(const struct MapLayout *);
@@ -146,7 +145,6 @@ extern bool8 warp0_in_pokecenter(void);
extern void ResetAllPicSprites(void);
extern void FieldEffectActiveListClear(void);
extern void SetUpFieldTasks(void);
-extern void sub_81BE6B8(void);
extern void ShowStartMenu(void);
extern void sub_80AEE84(void);
extern void mapldr_default(void);
@@ -1464,7 +1462,7 @@ static void overworld_bg_setup(void)
void overworld_free_bg_tilemaps(void)
{
- sub_81BE72C();
+ ClearMirageTowerPulseBlendEffect();
sub_81971F4();
if (gBGTilemapBuffers3 != NULL)
FREE_AND_SET_NULL(gBGTilemapBuffers3);
@@ -2121,7 +2119,7 @@ static void do_load_map_stuff_loop(u8 *state)
static void sub_80867C8(void)
{
- sub_81BE6AC();
+ ClearMirageTowerPulseBlend();
MoveSaveBlocks_ResetHeap();
}
@@ -2199,7 +2197,7 @@ static void sub_8086988(u32 a1)
if (!a1)
SetUpFieldTasks();
mapheader_run_script_with_tag_x5();
- sub_81BE6B8();
+ TryStartMirageTowerPulseBlendEffect();
}
static void sub_80869DC(void)
diff --git a/src/roulette_util.c b/src/roulette_util.c
index a197cfa09..c556a4af5 100755
--- a/src/roulette_util.c
+++ b/src/roulette_util.c
@@ -206,463 +206,227 @@ void sub_8151A9C(struct UnkStruct0 *r0, u16 r1)
}
}
-void sub_8151B3C(struct InnerStruct203CF18 *arg0)
+void InitPulseBlend(struct PulseBlend *pulseBlend)
{
u8 i = 0;
- arg0->unk0 = 0;
- memset(&arg0->unk4, 0, sizeof(arg0->unk4));
+ pulseBlend->usedPulseBlendPalettes = 0;
+ memset(&pulseBlend->pulseBlendPalettes, 0, sizeof(pulseBlend->pulseBlendPalettes));
for (; i < 16; i++)
- {
- arg0->unk4[i].unk0 = i;
- }
+ pulseBlend->pulseBlendPalettes[i].paletteSelector = i;
}
-int sub_8151B68(struct InnerStruct203CF18 *arg0, const struct InnerStruct203CF18_3 *arg1)
+int InitPulseBlendPaletteSettings(struct PulseBlend *pulseBlend, const struct PulseBlendSettings *settings)
{
u8 i = 0;
- struct InnerStruct203CF18_2 *r4 = NULL;
+ struct PulseBlendPalette *pulseBlendPalette = NULL;
- if (!arg0->unk4[0].unk1_7)
+ if (!pulseBlend->pulseBlendPalettes[0].inUse)
{
- r4 = &arg0->unk4[0];
+ pulseBlendPalette = &pulseBlend->pulseBlendPalettes[0];
}
else
{
while (++i < 16)
{
- if (!arg0->unk4[i].unk1_7)
+ if (!pulseBlend->pulseBlendPalettes[i].inUse)
{
- r4 = &arg0->unk4[i];
+ pulseBlendPalette = &pulseBlend->pulseBlendPalettes[i];
break;
}
}
}
- if (r4 == 0)
+ if (pulseBlendPalette == NULL)
return 0xFF;
- r4->unk1_0 = 0;
- r4->unk1_4 = 0;
- r4->unk1_6 = 1;
- r4->unk1_7 = 1;
- r4->unk2 = 0;
- r4->unk3 = 0;
- memcpy(&r4->unk4, arg1, sizeof(*arg1));
+ pulseBlendPalette->blendCoeff = 0;
+ pulseBlendPalette->fadeDirection = 0;
+ pulseBlendPalette->available = 1;
+ pulseBlendPalette->inUse = 1;
+ pulseBlendPalette->delayCounter = 0;
+ pulseBlendPalette->fadeCycleCounter = 0;
+ memcpy(&pulseBlendPalette->pulseBlendSettings, settings, sizeof(*settings));
return i;
}
-void sub_8151BD4(struct InnerStruct203CF18_2 *arg0)
+static void ClearPulseBlendPalettesSettings(struct PulseBlendPalette *pulseBlendPalette)
{
u16 i;
- if (!arg0->unk1_6 && arg0->unk4.unk7_6)
+ if (!pulseBlendPalette->available && pulseBlendPalette->pulseBlendSettings.restorePaletteOnUnload)
{
- for (i = arg0->unk4.unk2; i < arg0->unk4.unk2 + arg0->unk4.unk4; i++)
+ for (i = pulseBlendPalette->pulseBlendSettings.paletteOffset; i < pulseBlendPalette->pulseBlendSettings.paletteOffset + pulseBlendPalette->pulseBlendSettings.numColors; i++)
gPlttBufferFaded[i] = gPlttBufferUnfaded[i];
}
- memset(&arg0->unk4, 0, sizeof(arg0->unk4));
- arg0->unk1_0 = 0;
- arg0->unk1_4 = 0;
- arg0->unk1_5 = 0;
- arg0->unk1_6 = 1;
- arg0->unk1_7 = 0;
- arg0->unk3 = 0;
- arg0->unk2 = 0;
+ memset(&pulseBlendPalette->pulseBlendSettings, 0, sizeof(pulseBlendPalette->pulseBlendSettings));
+ pulseBlendPalette->blendCoeff = 0;
+ pulseBlendPalette->fadeDirection = 0;
+ pulseBlendPalette->unk1_5 = 0;
+ pulseBlendPalette->available = 1;
+ pulseBlendPalette->inUse = 0;
+ pulseBlendPalette->fadeCycleCounter = 0;
+ pulseBlendPalette->delayCounter = 0;
}
-void sub_8151C50(struct InnerStruct203CF18 *arg0, u16 arg1, u8 arg2)
+void UnloadUsedPulseBlendPalettes(struct PulseBlend *pulseBlend, u16 pulseBlendPaletteSelector, u8 multiSelection)
{
u16 i = 0;
- if (!arg2)
+ if (!multiSelection)
{
- sub_8151BD4(&arg0->unk4[arg1 & 0xF]);
+ ClearPulseBlendPalettesSettings(&pulseBlend->pulseBlendPalettes[pulseBlendPaletteSelector & 0xF]);
}
else
{
for (i = 0; i < 16; i++)
{
- if ((arg1 & 1) && arg0->unk4[i].unk1_7)
- sub_8151BD4(&arg0->unk4[i]);
+ if ((pulseBlendPaletteSelector & 1) && pulseBlend->pulseBlendPalettes[i].inUse)
+ ClearPulseBlendPalettesSettings(&pulseBlend->pulseBlendPalettes[i]);
- arg1 >>= 1;
+ pulseBlendPaletteSelector >>= 1;
}
}
}
-// there seems to be a temp var involved inside the first if block
-void sub_8151CA8(struct InnerStruct203CF18 *arg0, u16 arg1, u8 arg2)
+void MarkUsedPulseBlendPalettes(struct PulseBlend *pulseBlend, u16 pulseBlendPaletteSelector, u8 multiSelection)
{
u8 i = 0;
- if (!arg2)
+ if (!multiSelection)
{
- i = arg1 & 0xF;
- arg0->unk4[i].unk1_6 = 0;
- arg0->unk0 |= 1 << i;
+ i = pulseBlendPaletteSelector & 0xF;
+ pulseBlend->pulseBlendPalettes[i].available = 0;
+ pulseBlend->usedPulseBlendPalettes |= 1 << i;
}
else
{
for (i = 0; i < 16; i++)
{
- if (!(arg1 & 1) || !arg0->unk4[i].unk1_7 || !arg0->unk4[i].unk1_6)
+ if (!(pulseBlendPaletteSelector & 1) || !pulseBlend->pulseBlendPalettes[i].inUse || !pulseBlend->pulseBlendPalettes[i].available)
{
- arg1 <<= 1;
+ pulseBlendPaletteSelector <<= 1;
}
else
{
- arg0->unk4[i].unk1_6 = 0;
- arg0->unk0 |= 1 << i;
+ pulseBlend->pulseBlendPalettes[i].available = 0;
+ pulseBlend->usedPulseBlendPalettes |= 1 << i;
}
}
}
}
-void sub_8151D28(struct InnerStruct203CF18 *arg0, u16 arg1, u8 arg2)
+void UnmarkUsedPulseBlendPalettes(struct PulseBlend *pulseBlend, u16 pulseBlendPaletteSelector, u8 multiSelection)
{
u16 i;
- struct InnerStruct203CF18_2 *var0;
+ struct PulseBlendPalette *pulseBlendPalette;
u8 j = 0;
- if (!arg2)
+ if (!multiSelection)
{
- var0 = &arg0->unk4[arg1 & 0xF];
- if (!var0->unk1_6 && var0->unk1_7)
+ pulseBlendPalette = &pulseBlend->pulseBlendPalettes[pulseBlendPaletteSelector & 0xF];
+ if (!pulseBlendPalette->available && pulseBlendPalette->inUse)
{
- if (var0->unk4.unk7_6)
+ if (pulseBlendPalette->pulseBlendSettings.restorePaletteOnUnload)
{
- for (i = var0->unk4.unk2; i < var0->unk4.unk2 + var0->unk4.unk4; i++)
+ for (i = pulseBlendPalette->pulseBlendSettings.paletteOffset; i < pulseBlendPalette->pulseBlendSettings.paletteOffset + pulseBlendPalette->pulseBlendSettings.numColors; i++)
gPlttBufferFaded[i] = gPlttBufferUnfaded[i];
}
- var0->unk1_6 = 1;
- arg0->unk0 &= ~(1 << j);
+ pulseBlendPalette->available = 1;
+ pulseBlend->usedPulseBlendPalettes &= ~(1 << j);
}
}
else
{
for (j = 0; j < 16; j++)
{
- var0 = &arg0->unk4[j];
- if (!(arg1 & 1) || var0->unk1_6 || !var0->unk1_7)
+ pulseBlendPalette = &pulseBlend->pulseBlendPalettes[j];
+ if (!(pulseBlendPaletteSelector & 1) || pulseBlendPalette->available || !pulseBlendPalette->inUse)
{
- arg1 <<= 1;
+ pulseBlendPaletteSelector <<= 1;
}
else
{
- if (var0->unk4.unk7_6)
+ if (pulseBlendPalette->pulseBlendSettings.restorePaletteOnUnload)
{
- for (i = var0->unk4.unk2; i < var0->unk4.unk2 + var0->unk4.unk4; i++)
+ for (i = pulseBlendPalette->pulseBlendSettings.paletteOffset; i < pulseBlendPalette->pulseBlendSettings.paletteOffset + pulseBlendPalette->pulseBlendSettings.numColors; i++)
gPlttBufferFaded[i] = gPlttBufferUnfaded[i];
}
- var0->unk1_6 = 1;
- arg0->unk0 &= ~(1 << j);
+ pulseBlendPalette->available = 1;
+ pulseBlend->usedPulseBlendPalettes &= ~(1 << j);
}
}
}
}
-#ifdef NONMATCHING
-void sub_8151E50(struct InnerStruct203CF18 *arg0)
+void UpdatePulseBlend(struct PulseBlend *pulseBlend)
{
- struct InnerStruct203CF18_2 *var0;
+ struct PulseBlendPalette *pulseBlendPalette;
u8 i = 0;
- if (arg0->unk0)
+ if (pulseBlend->usedPulseBlendPalettes)
{
for (i = 0; i < 16; i++)
{
- var0 = &arg0->unk4[i];
- if ((!var0->unk1_6 && var0->unk1_7) && (!gPaletteFade.active || !var0->unk4.unk7_7))
+ pulseBlendPalette = &pulseBlend->pulseBlendPalettes[i];
+ if ((!pulseBlendPalette->available && pulseBlendPalette->inUse) && (!gPaletteFade.active || !pulseBlendPalette->pulseBlendSettings.unk7_7))
{
- if (--var0->unk2 == 0xFF)
+ if (--pulseBlendPalette->delayCounter == 0xFF)
{
- var0->unk2 = var0->unk4.unk5;
- BlendPalette(var0->unk4.unk2, var0->unk4.unk4, var0->unk1_0, var0->unk4.unk0);
- switch (var0->unk4.unk7_4)
+ pulseBlendPalette->delayCounter = pulseBlendPalette->pulseBlendSettings.delay;
+ BlendPalette(pulseBlendPalette->pulseBlendSettings.paletteOffset, pulseBlendPalette->pulseBlendSettings.numColors, pulseBlendPalette->blendCoeff, pulseBlendPalette->pulseBlendSettings.blendColor);
+ switch (pulseBlendPalette->pulseBlendSettings.fadeType)
{
- case 0:
- if (var0->unk1_0++ == var0->unk4.unk7_0)
+ case 0: // Fade all the way to the max blend amount, then wrap around
+ // BUG: This comparison will never be true for maxBlendCoeff values that are >= 8. This is because
+ // maxBlendCoeff is a signed 4-bit field, but blendCoeff is an unsigned 4-bit field. This code is never
+ // reached, anyway, so the bug is not observable in vanilla gameplay.
+ if (pulseBlendPalette->blendCoeff++ == pulseBlendPalette->pulseBlendSettings.maxBlendCoeff)
{
- var0->unk3++;
- var0->unk1_0 = 0;
+ pulseBlendPalette->fadeCycleCounter++;
+ pulseBlendPalette->blendCoeff = 0;
}
break;
- case 1:
- if (var0->unk1_4)
+ case 1: // Fade in and out
+ if (pulseBlendPalette->fadeDirection)
{
- if (--var0->unk1_0 == 0)
+ if (--pulseBlendPalette->blendCoeff == 0)
{
- var0->unk3++;
- var0->unk1_4 ^= 1;
+ pulseBlendPalette->fadeCycleCounter++;
+ pulseBlendPalette->fadeDirection ^= 1;
}
}
else
{
- if (var0->unk1_0++ == var0->unk4.unk7_0 - 1)
+ u8 max = (pulseBlendPalette->pulseBlendSettings.maxBlendCoeff - 1) & 0xF;
+ if (pulseBlendPalette->blendCoeff++ == max)
{
- var0->unk3++;
- var0->unk1_4 ^= 1;
+ pulseBlendPalette->fadeCycleCounter++;
+ pulseBlendPalette->fadeDirection ^= 1;
}
}
break;
- case 2:
- if (var0->unk1_4)
- var0->unk1_0 = 0;
+ case 2: // Flip back and forth
+ if (pulseBlendPalette->fadeDirection)
+ pulseBlendPalette->blendCoeff = 0;
else
- var0->unk1_0 = var0->unk4.unk7_0;
+ pulseBlendPalette->blendCoeff = pulseBlendPalette->pulseBlendSettings.maxBlendCoeff & 0xF;
- var0->unk1_4 ^= 1;
- var0->unk3++;
+ pulseBlendPalette->fadeDirection ^= 1;
+ pulseBlendPalette->fadeCycleCounter++;
break;
}
- if (var0->unk4.unk6 != 0xFF && var0->unk3 == 0xFF)
- sub_8151D28(arg0, var0->unk0, 0);
+ if (pulseBlendPalette->pulseBlendSettings.numFadeCycles != 0xFF
+ && pulseBlendPalette->fadeCycleCounter == pulseBlendPalette->pulseBlendSettings.numFadeCycles)
+ UnmarkUsedPulseBlendPalettes(pulseBlend, pulseBlendPalette->paletteSelector, FALSE);
}
}
}
}
}
-#else
-NAKED
-void sub_8151E50(struct InnerStruct203CF18 *arg0)
-{
- asm_unified("\n\
- push {r4-r7,lr}\n\
- mov r7, r10\n\
- mov r6, r9\n\
- mov r5, r8\n\
- push {r5-r7}\n\
- sub sp, 0x4\n\
- str r0, [sp]\n\
- movs r0, 0\n\
- mov r10, r0\n\
- ldr r1, [sp]\n\
- ldrh r0, [r1]\n\
- cmp r0, 0\n\
- bne _08151E6C\n\
- b _08151FF6\n\
-_08151E6C:\n\
- movs r2, 0xF\n\
- mov r9, r2\n\
- movs r3, 0x10\n\
- negs r3, r3\n\
- mov r8, r3\n\
- movs r7, 0x1\n\
-_08151E78:\n\
- mov r5, r10\n\
- lsls r0, r5, 1\n\
- add r0, r10\n\
- lsls r0, 2\n\
- adds r0, 0x4\n\
- ldr r1, [sp]\n\
- adds r4, r1, r0\n\
- ldrb r2, [r4, 0x1]\n\
- movs r3, 0xC0\n\
- ands r3, r2\n\
- cmp r3, 0x80\n\
- beq _08151E92\n\
- b _08151FE6\n\
-_08151E92:\n\
- ldr r0, =gPaletteFade\n\
- ldrb r1, [r0, 0x7]\n\
- adds r0, r3, 0\n\
- ands r0, r1\n\
- cmp r0, 0\n\
- beq _08151EA8\n\
- ldrb r0, [r4, 0xB]\n\
- ands r3, r0\n\
- cmp r3, 0\n\
- beq _08151EA8\n\
- b _08151FE6\n\
-_08151EA8:\n\
- ldrb r0, [r4, 0x2]\n\
- subs r0, 0x1\n\
- strb r0, [r4, 0x2]\n\
- lsls r0, 24\n\
- lsrs r0, 24\n\
- cmp r0, 0xFF\n\
- beq _08151EB8\n\
- b _08151FE6\n\
-_08151EB8:\n\
- ldrb r0, [r4, 0x9]\n\
- strb r0, [r4, 0x2]\n\
- ldrh r0, [r4, 0x6]\n\
- ldrb r1, [r4, 0x8]\n\
- lsls r2, 28\n\
- lsrs r2, 28\n\
- ldrh r3, [r4, 0x4]\n\
- bl BlendPalette\n\
- ldrb r5, [r4, 0xB]\n\
- lsls r0, r5, 26\n\
- asrs r0, 30\n\
- cmp r0, 0x1\n\
- beq _08151F16\n\
- cmp r0, 0x1\n\
- bgt _08151EE4\n\
- cmp r0, 0\n\
- beq _08151EEA\n\
- b _08151FD0\n\
- .pool\n\
-_08151EE4:\n\
- cmp r0, 0x2\n\
- beq _08151F92\n\
- b _08151FD0\n\
-_08151EEA:\n\
- ldrb r2, [r4, 0x1]\n\
- lsls r1, r2, 28\n\
- lsrs r0, r1, 28\n\
- adds r0, 0x1\n\
- mov r3, r9\n\
- ands r0, r3\n\
- mov r6, r8\n\
- adds r3, r6, 0\n\
- ands r3, r2\n\
- orrs r3, r0\n\
- strb r3, [r4, 0x1]\n\
- lsrs r1, 28\n\
- lsls r0, r5, 28\n\
- asrs r0, 28\n\
- cmp r1, r0\n\
- bne _08151FD0\n\
- ldrb r0, [r4, 0x3]\n\
- adds r0, 0x1\n\
- strb r0, [r4, 0x3]\n\
- ands r3, r6\n\
- strb r3, [r4, 0x1]\n\
- b _08151FD0\n\
-_08151F16:\n\
- ldrb r3, [r4, 0x1]\n\
- movs r0, 0x10\n\
- ands r0, r3\n\
- cmp r0, 0\n\
- beq _08151F54\n\
- lsls r0, r3, 28\n\
- lsrs r0, 28\n\
- subs r0, 0x1\n\
- mov r5, r9\n\
- ands r0, r5\n\
- mov r2, r8\n\
- ands r2, r3\n\
- orrs r2, r0\n\
- strb r2, [r4, 0x1]\n\
- cmp r0, 0\n\
- bne _08151FD0\n\
- ldrb r0, [r4, 0x3]\n\
- adds r0, 0x1\n\
- strb r0, [r4, 0x3]\n\
- lsls r0, r2, 27\n\
- lsrs r0, 31\n\
- eors r0, r7\n\
- ands r0, r7\n\
- lsls r0, 4\n\
- movs r3, 0x11\n\
- negs r3, r3\n\
- adds r1, r3, 0\n\
- ands r2, r1\n\
- orrs r2, r0\n\
- strb r2, [r4, 0x1]\n\
- b _08151FD0\n\
-_08151F54:\n\
- lsls r0, r5, 28\n\
- asrs r0, 28\n\
- subs r0, 0x1\n\
- mov r5, r9\n\
- ands r0, r5\n\
- lsls r2, r3, 28\n\
- lsrs r1, r2, 28\n\
- adds r1, 0x1\n\
- ands r1, r5\n\
- mov r5, r8\n\
- ands r3, r5\n\
- orrs r3, r1\n\
- strb r3, [r4, 0x1]\n\
- lsrs r2, 28\n\
- cmp r2, r0\n\
- bne _08151FD0\n\
- ldrb r0, [r4, 0x3]\n\
- adds r0, 0x1\n\
- strb r0, [r4, 0x3]\n\
- lsls r0, r3, 27\n\
- lsrs r0, 31\n\
- eors r0, r7\n\
- ands r0, r7\n\
- lsls r0, 4\n\
- movs r2, 0x11\n\
- negs r2, r2\n\
- adds r1, r2, 0\n\
- ands r3, r1\n\
- orrs r3, r0\n\
- strb r3, [r4, 0x1]\n\
- b _08151FD0\n\
-_08151F92:\n\
- ldrb r2, [r4, 0x1]\n\
- movs r0, 0x10\n\
- ands r0, r2\n\
- cmp r0, 0\n\
- beq _08151FA2\n\
- mov r0, r8\n\
- ands r0, r2\n\
- b _08151FB0\n\
-_08151FA2:\n\
- lsls r1, r5, 28\n\
- asrs r1, 28\n\
- mov r3, r9\n\
- ands r1, r3\n\
- mov r0, r8\n\
- ands r0, r2\n\
- orrs r0, r1\n\
-_08151FB0:\n\
- strb r0, [r4, 0x1]\n\
- ldrb r2, [r4, 0x1]\n\
- lsls r0, r2, 27\n\
- lsrs r0, 31\n\
- eors r0, r7\n\
- ands r0, r7\n\
- lsls r0, 4\n\
- movs r5, 0x11\n\
- negs r5, r5\n\
- adds r1, r5, 0\n\
- ands r2, r1\n\
- orrs r2, r0\n\
- strb r2, [r4, 0x1]\n\
- ldrb r0, [r4, 0x3]\n\
- adds r0, 0x1\n\
- strb r0, [r4, 0x3]\n\
-_08151FD0:\n\
- ldrb r1, [r4, 0xA]\n\
- cmp r1, 0xFF\n\
- beq _08151FE6\n\
- ldrb r0, [r4, 0x3]\n\
- cmp r0, r1\n\
- bne _08151FE6\n\
- ldrb r1, [r4]\n\
- ldr r0, [sp]\n\
- movs r2, 0\n\
- bl sub_8151D28\n\
-_08151FE6:\n\
- mov r0, r10\n\
- adds r0, 0x1\n\
- lsls r0, 24\n\
- lsrs r0, 24\n\
- mov r10, r0\n\
- cmp r0, 0xF\n\
- bhi _08151FF6\n\
- b _08151E78\n\
-_08151FF6:\n\
- add sp, 0x4\n\
- pop {r3-r5}\n\
- mov r8, r3\n\
- mov r9, r4\n\
- mov r10, r5\n\
- pop {r4-r7}\n\
- pop {r0}\n\
- bx r0");
-}
-#endif // NONMATCHING
void sub_8152008(u16 *dest, u16 src, u8 left, u8 top, u8 width, u8 height)
{