summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGriffinR <griffin.g.richards@gmail.com>2020-01-12 15:39:21 -0500
committerGriffinR <griffin.g.richards@gmail.com>2020-01-12 16:03:06 -0500
commitf2763832931127fc24e7cb9f9cdd85e3cf706a5c (patch)
treed23050509231d1d9c6d1694b2755c93fdaf26a4e /src
parentaa84a1d3a11c7cc6fd0e1021e1ed060e0c5683f2 (diff)
parent15ff7eb2f87032797f6ce9ef9bb471c468b48a36 (diff)
Merge master into sync-script
Diffstat (limited to 'src')
-rw-r--r--src/agb_flash.c2
-rw-r--r--src/battle_gfx_sfx_util.c4
-rw-r--r--src/battle_interface.c2800
-rw-r--r--src/battle_message.c2
-rw-r--r--src/battle_setup.c2
-rw-r--r--src/battle_tower.c2
-rw-r--r--src/data/text/map_section_names.h109
-rw-r--r--src/image_processing_effects.c4425
-rw-r--r--src/librfu_rfu.c2222
-rw-r--r--src/librfu_sio32id.c164
-rw-r--r--src/librfu_stwi.c647
-rw-r--r--src/main.c61
-rw-r--r--src/map_preview_screen.c2
-rw-r--r--src/party_menu.c2
-rw-r--r--src/party_menu_specials.c111
-rw-r--r--src/pc_screen_effect.c156
-rw-r--r--src/post_battle_event_funcs.c2
-rw-r--r--src/quest_log.c4
-rw-r--r--src/region_map.c4399
-rw-r--r--src/scrcmd.c3
-rw-r--r--src/script_pokemon_util.c218
-rw-r--r--src/text.c2
-rw-r--r--src/trade.c10
-rw-r--r--src/vs_seeker.c352
24 files changed, 15319 insertions, 382 deletions
diff --git a/src/agb_flash.c b/src/agb_flash.c
index 5b171abcb..7eb4ae737 100644
--- a/src/agb_flash.c
+++ b/src/agb_flash.c
@@ -74,7 +74,7 @@ u16 SetFlashTimerIntr(u8 timerNum, void (**intrFunc)(void))
return 1;
sTimerNum = timerNum;
- sTimerReg = &REG_TMCNT(sTimerNum);
+ sTimerReg = &REG_TMCNT_L(sTimerNum);
*intrFunc = FlashTimerIntr;
return 0;
}
diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c
index d7bccb298..60cff27be 100644
--- a/src/battle_gfx_sfx_util.c
+++ b/src/battle_gfx_sfx_util.c
@@ -687,8 +687,8 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, u8 notTransform)
gSprites[gBattlerSpriteIds[battlerAtk]].pos1.y = GetBattlerSpriteDefault_Y(battlerAtk);
StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerAtk]], gBattleMonForms[battlerAtk]);
SetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_NICKNAME, gSpeciesNames[targetSpecies]);
- sub_80496C0(gHealthboxSpriteIds[battlerAtk], &gEnemyParty[gBattlerPartyIndexes[battlerAtk]]);
- sub_804981C(gHealthboxSpriteIds[battlerAtk], 1);
+ UpdateNickInHealthbox(gHealthboxSpriteIds[battlerAtk], &gEnemyParty[gBattlerPartyIndexes[battlerAtk]]);
+ TryAddPokeballIconToHealthbox(gHealthboxSpriteIds[battlerAtk], 1);
}
else if (notTransform)
{
diff --git a/src/battle_interface.c b/src/battle_interface.c
new file mode 100644
index 000000000..6d16c0902
--- /dev/null
+++ b/src/battle_interface.c
@@ -0,0 +1,2800 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "battle_interface.h"
+#include "battle_message.h"
+#include "decompress.h"
+#include "gpu_regs.h"
+#include "graphics.h"
+#include "menu.h"
+#include "palette.h"
+#include "pokedex.h"
+#include "pokemon_summary_screen.h"
+#include "safari_zone.h"
+#include "sound.h"
+#include "string_util.h"
+#include "strings.h"
+#include "text.h"
+#include "window.h"
+#include "constants/songs.h"
+
+#define GetStringRightAlignXOffset(fontId, string, destWidth) ({ \
+ s32 w = GetStringWidth(fontId, string, 0); \
+ destWidth - w; \
+})
+
+#define abs(a) ((a) < 0 ? -(a) : (a))
+
+#define Q_24_8(n) ((s32)((n) * 256))
+#define Q_24_8_TO_INT(n) ((int)((n) >> 8))
+
+struct TestingBar
+{
+ s32 maxValue;
+ s32 oldValue;
+ s32 receivedValue;
+ u32 pal:5;
+ u32 tileOffset;
+};
+
+enum
+{ // Corresponds to gHealthboxElementsGfxTable (and the tables after it) in graphics.c
+ // These are indexes into the tables, which are filled with 8x8 square pixel data.
+ HEALTHBOX_GFX_0, //hp bar [black section]
+ HEALTHBOX_GFX_1, //hp bar "H"
+ HEALTHBOX_GFX_2, //hp bar "P"
+ HEALTHBOX_GFX_HP_BAR_GREEN, //hp bar [0 pixels]
+ HEALTHBOX_GFX_4, //hp bar [1 pixels]
+ HEALTHBOX_GFX_5, //hp bar [2 pixels]
+ HEALTHBOX_GFX_6, //hp bar [3 pixels]
+ HEALTHBOX_GFX_7, //hp bar [4 pixels]
+ HEALTHBOX_GFX_8, //hp bar [5 pixels]
+ HEALTHBOX_GFX_9, //hp bar [6 pixels]
+ HEALTHBOX_GFX_10, //hp bar [7 pixels]
+ HEALTHBOX_GFX_11, //hp bar [8 pixels]
+ HEALTHBOX_GFX_12, //exp bar [0 pixels]
+ HEALTHBOX_GFX_13, //exp bar [1 pixels]
+ HEALTHBOX_GFX_14, //exp bar [2 pixels]
+ HEALTHBOX_GFX_15, //exp bar [3 pixels]
+ HEALTHBOX_GFX_16, //exp bar [4 pixels]
+ HEALTHBOX_GFX_17, //exp bar [5 pixels]
+ HEALTHBOX_GFX_18, //exp bar [6 pixels]
+ HEALTHBOX_GFX_19, //exp bar [7 pixels]
+ HEALTHBOX_GFX_20, //exp bar [8 pixels]
+ HEALTHBOX_GFX_STATUS_PSN_BATTLER0, //status psn "(P"
+ HEALTHBOX_GFX_22, //status psn "SN"
+ HEALTHBOX_GFX_23, //status psn "|)""
+ HEALTHBOX_GFX_STATUS_PRZ_BATTLER0, //status prz
+ HEALTHBOX_GFX_25,
+ HEALTHBOX_GFX_26,
+ HEALTHBOX_GFX_STATUS_SLP_BATTLER0, //status slp
+ HEALTHBOX_GFX_28,
+ HEALTHBOX_GFX_29,
+ HEALTHBOX_GFX_STATUS_FRZ_BATTLER0, //status frz
+ HEALTHBOX_GFX_31,
+ HEALTHBOX_GFX_32,
+ HEALTHBOX_GFX_STATUS_BRN_BATTLER0, //status brn
+ HEALTHBOX_GFX_34,
+ HEALTHBOX_GFX_35,
+ HEALTHBOX_GFX_36, //misc [Black section]
+ HEALTHBOX_GFX_37, //misc [Black section]
+ HEALTHBOX_GFX_38, //misc [Black section]
+ HEALTHBOX_GFX_39, //misc [Blank Health Window?]
+ HEALTHBOX_GFX_40, //misc [Blank Health Window?]
+ HEALTHBOX_GFX_41, //misc [Blank Health Window?]
+ HEALTHBOX_GFX_42, //misc [Blank Health Window?]
+ HEALTHBOX_GFX_43, //misc [Top of Health Window?]
+ HEALTHBOX_GFX_44, //misc [Top of Health Window?]
+ HEALTHBOX_GFX_45, //misc [Top of Health Window?]
+ HEALTHBOX_GFX_46, //misc [Blank Health Window?]
+ HEALTHBOX_GFX_HP_BAR_YELLOW, //hp bar yellow [0 pixels]
+ HEALTHBOX_GFX_48, //hp bar yellow [1 pixels]
+ HEALTHBOX_GFX_49, //hp bar yellow [2 pixels]
+ HEALTHBOX_GFX_50, //hp bar yellow [3 pixels]
+ HEALTHBOX_GFX_51, //hp bar yellow [4 pixels]
+ HEALTHBOX_GFX_52, //hp bar yellow [5 pixels]
+ HEALTHBOX_GFX_53, //hp bar yellow [6 pixels]
+ HEALTHBOX_GFX_54, //hp bar yellow [7 pixels]
+ HEALTHBOX_GFX_55, //hp bar yellow [8 pixels]
+ HEALTHBOX_GFX_HP_BAR_RED, //hp bar red [0 pixels]
+ HEALTHBOX_GFX_57, //hp bar red [1 pixels]
+ HEALTHBOX_GFX_58, //hp bar red [2 pixels]
+ HEALTHBOX_GFX_59, //hp bar red [3 pixels]
+ HEALTHBOX_GFX_60, //hp bar red [4 pixels]
+ HEALTHBOX_GFX_61, //hp bar red [5 pixels]
+ HEALTHBOX_GFX_62, //hp bar red [6 pixels]
+ HEALTHBOX_GFX_63, //hp bar red [7 pixels]
+ HEALTHBOX_GFX_64, //hp bar red [8 pixels]
+ HEALTHBOX_GFX_65, //hp bar frame end
+ HEALTHBOX_GFX_66, //status ball [full]
+ HEALTHBOX_GFX_67, //status ball [empty]
+ HEALTHBOX_GFX_68, //status ball [fainted]
+ HEALTHBOX_GFX_69, //status ball [statused]
+ HEALTHBOX_GFX_70, //status ball [unused extra]
+ HEALTHBOX_GFX_STATUS_PSN_BATTLER1, //status2 "PSN"
+ HEALTHBOX_GFX_72,
+ HEALTHBOX_GFX_73,
+ HEALTHBOX_GFX_STATUS_PRZ_BATTLER1, //status2 "PRZ"
+ HEALTHBOX_GFX_75,
+ HEALTHBOX_GFX_76,
+ HEALTHBOX_GFX_STATUS_SLP_BATTLER1, //status2 "SLP"
+ HEALTHBOX_GFX_78,
+ HEALTHBOX_GFX_79,
+ HEALTHBOX_GFX_STATUS_FRZ_BATTLER1, //status2 "FRZ"
+ HEALTHBOX_GFX_81,
+ HEALTHBOX_GFX_82,
+ HEALTHBOX_GFX_STATUS_BRN_BATTLER1, //status2 "BRN"
+ HEALTHBOX_GFX_84,
+ HEALTHBOX_GFX_85,
+ HEALTHBOX_GFX_STATUS_PSN_BATTLER2, //status3 "PSN"
+ HEALTHBOX_GFX_87,
+ HEALTHBOX_GFX_88,
+ HEALTHBOX_GFX_STATUS_PRZ_BATTLER2, //status3 "PRZ"
+ HEALTHBOX_GFX_90,
+ HEALTHBOX_GFX_91,
+ HEALTHBOX_GFX_STATUS_SLP_BATTLER2, //status3 "SLP"
+ HEALTHBOX_GFX_93,
+ HEALTHBOX_GFX_94,
+ HEALTHBOX_GFX_STATUS_FRZ_BATTLER2, //status3 "FRZ"
+ HEALTHBOX_GFX_96,
+ HEALTHBOX_GFX_97,
+ HEALTHBOX_GFX_STATUS_BRN_BATTLER2, //status3 "BRN"
+ HEALTHBOX_GFX_99,
+ HEALTHBOX_GFX_100,
+ HEALTHBOX_GFX_STATUS_PSN_BATTLER3, //status4 "PSN"
+ HEALTHBOX_GFX_102,
+ HEALTHBOX_GFX_103,
+ HEALTHBOX_GFX_STATUS_PRZ_BATTLER3, //status4 "PRZ"
+ HEALTHBOX_GFX_105,
+ HEALTHBOX_GFX_106,
+ HEALTHBOX_GFX_STATUS_SLP_BATTLER3, //status4 "SLP"
+ HEALTHBOX_GFX_108,
+ HEALTHBOX_GFX_109,
+ HEALTHBOX_GFX_STATUS_FRZ_BATTLER3, //status4 "FRZ"
+ HEALTHBOX_GFX_111,
+ HEALTHBOX_GFX_112,
+ HEALTHBOX_GFX_STATUS_BRN_BATTLER3, //status4 "BRN"
+ HEALTHBOX_GFX_114,
+ HEALTHBOX_GFX_115,
+ HEALTHBOX_GFX_116, //unknown_D12FEC
+ HEALTHBOX_GFX_117, //unknown_D1300C
+};
+
+static void SpriteCB_HealthBoxOther(struct Sprite * sprite);
+static void SpriteCB_HealthBar(struct Sprite * sprite);
+static const u8 *GetHealthboxElementGfxPtr(u8 which);
+static void UpdateHpTextInHealthboxInDoubles(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent);
+static void sub_8049388(u8 taskId);
+static void sub_80493E4(u8 taskId);
+static void sub_8049568(struct Sprite * sprite);
+static void sub_8049630(struct Sprite * sprite);
+static void sub_804948C(u8 taskId);
+static void SpriteCB_StatusSummaryBallsOnSwitchout(struct Sprite * sprite);
+static void UpdateStatusIconInHealthbox(u8 spriteId);
+static void SpriteCB_StatusSummaryBar(struct Sprite * sprite);
+static void SpriteCB_StatusSummaryBallsOnBattleStart(struct Sprite * sprite);
+static u8 GetStatusIconForBattlerId(u8 statusElementId, u8 battlerId);
+static void MoveBattleBarGraphically(u8 battlerId, u8 whichBar);
+static u8 GetScaledExpFraction(s32 oldValue, s32 receivedValue, s32 maxValue, u8 scale);
+static u8 CalcBarFilledPixels(s32 maxValue, s32 oldValue, s32 receivedValue, s32 *currValue, u8 *arg4, u8 scale);
+static s32 CalcNewBarValue(s32 maxValue, s32 currValue, s32 receivedValue, s32 *arg3, u8 arg4, u16 arg5);
+static void sub_804A510(struct TestingBar *barInfo, s32 *currValue, u8 bg, u8 x, u8 y);
+static void SafariTextIntoHealthboxObject(void *dest, u8 *windowTileData, u32 windowWidth);
+static u8 *AddTextPrinterAndCreateWindowOnHealthbox(const u8 *str, u32 x, u32 y, u32 *windowId);
+static void RemoveWindowOnHealthbox(u32 windowId);
+static void TextIntoHealthboxObject(void *dest, u8 *windowTileData, s32 windowWidth);
+
+static const struct OamData gOamData_8260270 = {
+ .shape = SPRITE_SHAPE(64x32),
+ .size = SPRITE_SIZE(64x32),
+ .priority = 1
+};
+
+static const struct SpriteTemplate sHealthboxPlayerSpriteTemplates[] = {
+ {
+ .tileTag = 55039,
+ .paletteTag = 55039,
+ .oam = &gOamData_8260270,
+ .anims = gDummySpriteAnimTable,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy
+ }, {
+ .tileTag = 55040,
+ .paletteTag = 55039,
+ .oam = &gOamData_8260270,
+ .anims = gDummySpriteAnimTable,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy
+ }
+};
+
+static const struct SpriteTemplate sHealthboxOpponentSpriteTemplates[] = {
+ {
+ .tileTag = 55041,
+ .paletteTag = 55039,
+ .oam = &gOamData_8260270,
+ .anims = gDummySpriteAnimTable,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy
+ }, {
+ .tileTag = 55042,
+ .paletteTag = 55039,
+ .oam = &gOamData_8260270,
+ .anims = gDummySpriteAnimTable,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy
+ }
+};
+
+static const struct SpriteTemplate sHealthboxSafariSpriteTemplate =
+{
+ .tileTag = 55051,
+ .paletteTag = 55039,
+ .oam = &gOamData_8260270,
+ .anims = gDummySpriteAnimTable,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy
+};
+
+static const struct OamData gUnknown_82602F0 = {
+ .shape = SPRITE_SHAPE(32x8),
+ .size = SPRITE_SIZE(32x8),
+ .priority = 1
+};
+
+static const struct SpriteTemplate gUnknown_82602F8[] = {
+ {
+ .tileTag = 55044,
+ .paletteTag = 55044,
+ .oam = &gUnknown_82602F0,
+ .anims = gDummySpriteAnimTable,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_HealthBar
+ }, {
+ .tileTag = 55045,
+ .paletteTag = 55044,
+ .oam = &gUnknown_82602F0,
+ .anims = gDummySpriteAnimTable,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_HealthBar
+ }, {
+ .tileTag = 55046,
+ .paletteTag = 55044,
+ .oam = &gUnknown_82602F0,
+ .anims = gDummySpriteAnimTable,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_HealthBar
+ }, {
+ .tileTag = 55047,
+ .paletteTag = 55044,
+ .oam = &gUnknown_82602F0,
+ .anims = gDummySpriteAnimTable,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_HealthBar
+ }
+};
+
+static const struct Subsprite gUnknown_8260358[] = {
+ { 240, 0, SPRITE_SHAPE(64x32), SPRITE_SIZE(64x32), 0x0000, 1 },
+ { 48, 0, SPRITE_SHAPE(32x32), SPRITE_SIZE(32x32), 0x0020, 1 },
+ { 240, 32, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0030, 1 },
+ { 16, 32, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0034, 1 },
+ { 48, 32, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0038, 1 }
+};
+
+static const struct Subsprite gUnknown_826036C[] = {
+ { 240, 0, SPRITE_SHAPE(64x32), SPRITE_SIZE(64x32), 0x0040, 1 },
+ { 48, 0, SPRITE_SHAPE(32x32), SPRITE_SIZE(32x32), 0x0060, 1 },
+ { 240, 32, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0070, 1 },
+ { 16, 32, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0074, 1 },
+ { 48, 32, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0078, 1 }
+};
+
+static const struct Subsprite gUnknown_8260380[] = {
+ { 240, 0, SPRITE_SHAPE(64x32), SPRITE_SIZE(64x32), 0x0000, 1 },
+ { 48, 0, SPRITE_SHAPE(32x32), SPRITE_SIZE(32x32), 0x0020, 1 }
+};
+
+static const struct Subsprite gUnknown_8260388[] = {
+ { 240, 0, SPRITE_SHAPE(64x32), SPRITE_SIZE(64x32), 0x0000, 1 },
+ { 48, 0, SPRITE_SHAPE(32x32), SPRITE_SIZE(32x32), 0x0020, 1 }
+};
+
+static const struct Subsprite gUnknown_8260390[] = {
+ { 240, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0000, 1 },
+ { 16, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0004, 1 }
+};
+
+static const struct Subsprite gUnknown_8260398[] = {
+ { 240, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0000, 1 },
+ { 16, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0004, 1 },
+ { 224, 0, SPRITE_SHAPE(8x8), SPRITE_SIZE(8x8), 0x0008, 1 }
+};
+
+static const struct SubspriteTable gUnknown_82603A4[] = {
+ {NELEMS(gUnknown_8260358), gUnknown_8260358},
+ {NELEMS(gUnknown_8260380), gUnknown_8260380},
+ {NELEMS(gUnknown_826036C), gUnknown_826036C},
+ {NELEMS(gUnknown_8260388), gUnknown_8260388}
+};
+
+static const struct SubspriteTable gUnknown_82603C4[] = {
+ {NELEMS(gUnknown_8260390), gUnknown_8260390},
+ {NELEMS(gUnknown_8260398), gUnknown_8260398}
+};
+
+static const struct Subsprite gUnknown_82603D4[] = {
+ { 160, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0000, 1 },
+ { 192, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0004, 1 },
+ { 224, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0008, 1 },
+ { 0, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x000c, 1 }
+};
+
+static const struct Subsprite gUnknown_82603E4[] = {
+ { 160, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0000, 1 },
+ { 192, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0004, 1 },
+ { 224, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0008, 1 },
+ { 0, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0008, 1 },
+ { 32, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0008, 1 },
+ { 64, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x000c, 1 }
+};
+
+static const struct SubspriteTable sStatusSummaryBar_SubspriteTable[] =
+{
+ {NELEMS(gUnknown_82603D4), gUnknown_82603D4}
+};
+
+static const struct SubspriteTable gUnknown_8260404[] = {
+ {NELEMS(gUnknown_82603E4), gUnknown_82603E4}
+};
+
+static const u16 gUnknown_26040C[] = INCBIN_U16("graphics/battle_interface/unk_826404C.4bpp");
+
+static const struct CompressedSpriteSheet sStatusSummaryBarSpriteSheets[] = {
+ {gFile_graphics_battle_interface_ball_status_bar_sheet, 0x0200, 55052},
+ {gFile_graphics_battle_interface_ball_status_bar_sheet, 0x0200, 55053}
+};
+
+static const struct SpritePalette sStatusSummaryBarSpritePals[] = {
+ {gBattleInterface_BallStatusBarPal, 55056},
+ {gBattleInterface_BallStatusBarPal, 55057}
+};
+
+static const struct SpritePalette sStatusSummaryBallsSpritePals[] = {
+ {gBattleInterface_BallDisplayPal, 55058},
+ {gBattleInterface_BallDisplayPal, 55059}
+};
+
+static const struct SpriteSheet sStatusSummaryBallsSpriteSheets[] = {
+ {gUnknown_8D12404, 0x0080, 55060},
+ {gUnknown_8D12404, 0x0080, 55061}
+};
+
+static const struct OamData gUnknown_82604AC = {
+ .shape = SPRITE_SHAPE(64x32),
+ .size = SPRITE_SIZE(64x32),
+ .priority = 1
+};
+
+static const struct OamData gUnknown_82604B4 = {
+ .shape = SPRITE_SHAPE(8x8),
+ .size = SPRITE_SIZE(8x8),
+ .priority = 1
+};
+
+static const struct SpriteTemplate sStatusSummaryBarSpriteTemplates[] = {
+ {
+ .tileTag = 55052,
+ .paletteTag = 55056,
+ .oam = &gOamData_8260270,
+ .anims = gDummySpriteAnimTable,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_StatusSummaryBar
+ }, {
+ .tileTag = 55053,
+ .paletteTag = 55057,
+ .oam = &gOamData_8260270,
+ .anims = gDummySpriteAnimTable,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_StatusSummaryBar
+ }
+};
+
+static const struct SpriteTemplate sStatusSummaryBallsSpriteTemplates[] = {
+ {
+ .tileTag = 55060,
+ .paletteTag = 55058,
+ .oam = &gUnknown_82604B4,
+ .anims = gDummySpriteAnimTable,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_StatusSummaryBallsOnBattleStart
+ }, {
+ .tileTag = 55061,
+ .paletteTag = 55059,
+ .oam = &gUnknown_82604B4,
+ .anims = gDummySpriteAnimTable,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_StatusSummaryBallsOnBattleStart
+ }
+};
+
+static void sub_8047B0C(s16 number, u16 *dest, bool8 unk)
+{
+ s8 i, j;
+ u8 buff[4];
+
+ for (i = 0; i < 4; i++)
+ {
+ buff[i] = 0;
+ }
+
+ for (i = 3; ; i--)
+ {
+ if (number > 0)
+ {
+ buff[i] = number % 10;
+ number /= 10;
+ }
+ else
+ {
+ for (; i > -1; i--)
+ {
+ buff[i] = 0xFF;
+ }
+ if (buff[3] == 0xFF)
+ buff[3] = 0;
+ break;
+ }
+ }
+
+
+
+ if (!unk)
+ {
+ for (i = 0, j = 0; i < 4; i++)
+ {
+ if (buff[j] == 0xFF)
+ {
+ dest[j + 0x00] &= 0xFC00;
+ dest[j + 0x00] |= 0x1E;
+ dest[i + 0x20] &= 0xFC00;
+ dest[i + 0x20] |= 0x1E;
+ }
+ else
+ {
+ dest[j + 0x00] &= 0xFC00;
+ dest[j + 0x00] |= 0x14 + buff[j];
+ dest[i + 0x20] &= 0xFC00;
+ dest[i + 0x20] |= 0x34 + buff[i];
+ }
+ j++;
+ }
+ }
+ else
+ {
+ for (i = 0; i < 4; i++)
+ {
+ if (buff[i] == 0xFF)
+ {
+ dest[i + 0x00] &= 0xFC00;
+ dest[i + 0x00] |= 0x1E;
+ dest[i + 0x20] &= 0xFC00;
+ dest[i + 0x20] |= 0x1E;
+ }
+ else
+ {
+ dest[i + 0x00] &= 0xFC00;
+ dest[i + 0x00] |= 0x14 + buff[i];
+ dest[i + 0x20] &= 0xFC00;
+ dest[i + 0x20] |= 0x34 + buff[i];
+ }
+ }
+ }
+}
+
+static void sub_8047CAC(s16 num1, s16 num2, u16 *dest)
+{
+ dest[4] = 0x1E;
+ sub_8047B0C(num2, &dest[0], FALSE);
+ sub_8047B0C(num1, &dest[5], TRUE);
+}
+
+// Because the healthbox is too large to fit into one sprite, it is divided into two sprites.
+// healthboxLeft or healthboxMain is the left part that is used as the 'main' sprite.
+// healthboxRight or healthboxOther is the right part of the healthbox.
+// There's also the third sprite under name of healthbarSprite that refers to the healthbar visible on the healtbox.
+
+// data fields for healthboxMain
+// oam.affineParam holds healthboxRight spriteId
+#define hMain_HealthBarSpriteId data[5]
+#define hMain_Battler data[6]
+#define hMain_Data7 data[7]
+
+// data fields for healthboxRight
+#define hOther_HealthBoxSpriteId data[5]
+
+// data fields for healthbar
+#define hBar_HealthBoxSpriteId data[5]
+#define hBar_Data6 data[6]
+
+u8 CreateBattlerHealthboxSprites(u8 a)
+{
+ s16 data6 = 0;
+ u8 healthboxLeftSpriteId;
+ u8 healthboxRightSpriteId;
+ u8 healthbarSpriteId;
+ struct Sprite *sprite;
+
+ if (!IsDoubleBattle())
+ {
+ if (GetBattlerSide(a) == B_SIDE_PLAYER)
+ {
+ healthboxLeftSpriteId = CreateSprite(&sHealthboxPlayerSpriteTemplates[0], 240, 160, 1);
+ healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxPlayerSpriteTemplates[0], 240, 160, 1);
+
+ gSprites[healthboxLeftSpriteId].oam.shape = SPRITE_SHAPE(64x64);
+ gSprites[healthboxRightSpriteId].oam.shape = SPRITE_SHAPE(64x64);
+ gSprites[healthboxRightSpriteId].oam.tileNum += 64;
+ }
+ else
+ {
+ healthboxLeftSpriteId = CreateSprite(&sHealthboxOpponentSpriteTemplates[0], 240, 160, 1);
+ healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxOpponentSpriteTemplates[0], 240, 160, 1);
+
+ gSprites[healthboxRightSpriteId].oam.tileNum += 32;
+ data6 = 2;
+ }
+
+ gSprites[healthboxLeftSpriteId].oam.affineParam = healthboxRightSpriteId;
+ gSprites[healthboxRightSpriteId].hBar_HealthBoxSpriteId = healthboxLeftSpriteId;
+ gSprites[healthboxRightSpriteId].callback = SpriteCB_HealthBoxOther;
+ }
+ else
+ {
+ if (GetBattlerSide(a) == B_SIDE_PLAYER)
+ {
+ healthboxLeftSpriteId = CreateSprite(&sHealthboxPlayerSpriteTemplates[GetBattlerPosition(a) / 2], 240, 160, 1);
+ healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxPlayerSpriteTemplates[GetBattlerPosition(a) / 2], 240, 160, 1);
+
+ gSprites[healthboxLeftSpriteId].oam.affineParam = healthboxRightSpriteId;
+ gSprites[healthboxRightSpriteId].hBar_HealthBoxSpriteId = healthboxLeftSpriteId;
+ gSprites[healthboxRightSpriteId].oam.tileNum += 32;
+ gSprites[healthboxRightSpriteId].callback = SpriteCB_HealthBoxOther;
+ data6 = 1;
+ }
+ else
+ {
+ healthboxLeftSpriteId = CreateSprite(&sHealthboxOpponentSpriteTemplates[GetBattlerPosition(a) / 2], 240, 160, 1);
+ healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxOpponentSpriteTemplates[GetBattlerPosition(a) / 2], 240, 160, 1);
+
+ gSprites[healthboxLeftSpriteId].oam.affineParam = healthboxRightSpriteId;
+ gSprites[healthboxRightSpriteId].hBar_HealthBoxSpriteId = healthboxLeftSpriteId;
+ gSprites[healthboxRightSpriteId].oam.tileNum += 32;
+ gSprites[healthboxRightSpriteId].callback = SpriteCB_HealthBoxOther;
+ data6 = 2;
+ }
+ }
+ healthbarSpriteId = CreateSpriteAtEnd(&gUnknown_82602F8[gBattlerPositions[a]], 140, 60, 0);
+ sprite = &gSprites[healthbarSpriteId];
+ SetSubspriteTables(sprite, &gUnknown_82603C4[GetBattlerSide(a)]);
+ sprite->subspriteMode = SUBSPRITES_IGNORE_PRIORITY;
+ sprite->oam.priority = 1;
+ CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_1), OBJ_VRAM0 + sprite->oam.tileNum * 32, 64);
+
+ gSprites[healthboxLeftSpriteId].hBar_HealthBoxSpriteId = healthbarSpriteId;
+ gSprites[healthboxLeftSpriteId].hBar_Data6 = a;
+ gSprites[healthboxLeftSpriteId].invisible = TRUE;
+ gSprites[healthboxRightSpriteId].invisible = TRUE;
+ sprite->data[5] = healthboxLeftSpriteId;
+ sprite->data[6] = data6;
+ sprite->invisible = TRUE;
+
+ return healthboxLeftSpriteId;
+}
+
+u8 CreateSafariPlayerHealthboxSprites(void)
+{
+ u8 healthboxLeftSpriteId = CreateSprite(&sHealthboxSafariSpriteTemplate, 240, 160, 1);
+ u8 healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxSafariSpriteTemplate, 240, 160, 1);
+
+ gSprites[healthboxLeftSpriteId].oam.shape = SPRITE_SHAPE(64x64);
+ gSprites[healthboxRightSpriteId].oam.shape = SPRITE_SHAPE(64x64);
+ gSprites[healthboxRightSpriteId].oam.tileNum += 0x40;
+ gSprites[healthboxLeftSpriteId].oam.affineParam = healthboxRightSpriteId;
+ gSprites[healthboxRightSpriteId].hBar_HealthBoxSpriteId = healthboxLeftSpriteId;
+ gSprites[healthboxRightSpriteId].callback = SpriteCB_HealthBoxOther;
+ return healthboxLeftSpriteId;
+}
+
+static const u8 *GetHealthboxElementGfxPtr(u8 elementId)
+{
+ return gHealthboxElementsGfxTable[elementId];
+}
+
+// Syncs the position of healthbar accordingly with the healthbox.
+static void SpriteCB_HealthBar(struct Sprite *sprite)
+{
+ u8 r5 = sprite->data[5];
+
+ switch (sprite->data[6])
+ {
+ case 0:
+ sprite->pos1.x = gSprites[r5].pos1.x + 16;
+ sprite->pos1.y = gSprites[r5].pos1.y;
+ break;
+ case 1:
+ sprite->pos1.x = gSprites[r5].pos1.x + 16;
+ sprite->pos1.y = gSprites[r5].pos1.y;
+ break;
+ default:
+ case 2:
+ sprite->pos1.x = gSprites[r5].pos1.x + 8;
+ sprite->pos1.y = gSprites[r5].pos1.y;
+ break;
+ }
+ sprite->pos2.x = gSprites[r5].pos2.x;
+ sprite->pos2.y = gSprites[r5].pos2.y;
+}
+
+static void SpriteCB_HealthBoxOther(struct Sprite *sprite)
+{
+ u8 healthboxMainSpriteId = sprite->hOther_HealthBoxSpriteId;
+
+ sprite->pos1.x = gSprites[healthboxMainSpriteId].pos1.x + 64;
+ sprite->pos1.y = gSprites[healthboxMainSpriteId].pos1.y;
+
+ sprite->pos2.x = gSprites[healthboxMainSpriteId].pos2.x;
+ sprite->pos2.y = gSprites[healthboxMainSpriteId].pos2.y;
+}
+
+void SetBattleBarStruct(u8 battlerId, u8 healthboxSpriteId, s32 maxVal, s32 oldVal, s32 receivedValue)
+{
+ gBattleSpritesDataPtr->battleBars[battlerId].healthboxSpriteId = healthboxSpriteId;
+ gBattleSpritesDataPtr->battleBars[battlerId].maxValue = maxVal;
+ gBattleSpritesDataPtr->battleBars[battlerId].oldValue = oldVal;
+ gBattleSpritesDataPtr->battleBars[battlerId].receivedValue = receivedValue;
+ gBattleSpritesDataPtr->battleBars[battlerId].currValue = -32768;
+}
+
+void SetHealthboxSpriteInvisible(u8 healthboxSpriteId)
+{
+ gSprites[healthboxSpriteId].invisible = TRUE;
+ gSprites[gSprites[healthboxSpriteId].hMain_HealthBarSpriteId].invisible = TRUE;
+ gSprites[gSprites[healthboxSpriteId].oam.affineParam].invisible = TRUE;
+}
+
+void SetHealthboxSpriteVisible(u8 healthboxSpriteId)
+{
+ gSprites[healthboxSpriteId].invisible = FALSE;
+ gSprites[gSprites[healthboxSpriteId].hMain_HealthBarSpriteId].invisible = FALSE;
+ gSprites[gSprites[healthboxSpriteId].oam.affineParam].invisible = FALSE;
+}
+
+static void UpdateSpritePos(u8 spriteId, s16 x, s16 y)
+{
+ gSprites[spriteId].pos1.x = x;
+ gSprites[spriteId].pos1.y = y;
+}
+
+void DestoryHealthboxSprite(u8 healthboxSpriteId)
+{
+ DestroySprite(&gSprites[gSprites[healthboxSpriteId].oam.affineParam]);
+ DestroySprite(&gSprites[gSprites[healthboxSpriteId].hMain_HealthBarSpriteId]);
+ DestroySprite(&gSprites[healthboxSpriteId]);
+}
+
+void DummyBattleInterfaceFunc(u8 healthboxSpriteId, bool8 isDoubleBattleBattlerOnly)
+{
+
+}
+
+void UpdateOamPriorityInAllHealthboxes(u8 priority)
+{
+ s32 i;
+
+ for (i = 0; i < gBattlersCount; i++)
+ {
+ u8 healthboxLeftSpriteId = gHealthboxSpriteIds[i];
+ u8 healthboxRightSpriteId = gSprites[gHealthboxSpriteIds[i]].oam.affineParam;
+ u8 healthbarSpriteId = gSprites[gHealthboxSpriteIds[i]].hMain_HealthBarSpriteId;
+
+ gSprites[healthboxLeftSpriteId].oam.priority = priority;
+ gSprites[healthboxRightSpriteId].oam.priority = priority;
+ gSprites[healthbarSpriteId].oam.priority = priority;
+ }
+}
+
+void InitBattlerHealthboxCoords(u8 battler)
+{
+ s16 x = 0, y = 0;
+
+ if (!IsDoubleBattle())
+ {
+ if (GetBattlerSide(battler) != B_SIDE_PLAYER)
+ x = 44, y = 30;
+ else
+ x = 158, y = 88;
+ }
+ else
+ {
+ switch (GetBattlerPosition(battler))
+ {
+ case B_POSITION_PLAYER_LEFT:
+ x = 159, y = 75;
+ break;
+ case B_POSITION_PLAYER_RIGHT:
+ x = 171, y = 100;
+ break;
+ case B_POSITION_OPPONENT_LEFT:
+ x = 44, y = 19;
+ break;
+ case B_POSITION_OPPONENT_RIGHT:
+ x = 32, y = 44;
+ break;
+ }
+ }
+
+ UpdateSpritePos(gHealthboxSpriteIds[battler], x, y);
+}
+
+static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl)
+{
+ u32 windowId, spriteTileNum;
+ u8 *windowTileData;
+ u8 text[16] = _("{LV_2}");
+ u32 xPos, var1;
+ void *objVram;
+
+ xPos = (u32) ConvertIntToDecimalStringN(text + 2, lvl, STR_CONV_MODE_LEFT_ALIGN, 3);
+ // Alright, that part was unmatchable. It's basically doing:
+ // xPos = 5 * (3 - (u32)(&text[2]));
+ xPos--;
+ xPos--;
+ xPos -= ((u32)(text));
+ var1 = (3 - xPos);
+ xPos = 4 * var1;
+ xPos += var1;
+
+ windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, xPos, 3, &windowId);
+ spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum * TILE_SIZE_4BPP;
+
+ if (GetBattlerSide(gSprites[healthboxSpriteId].hMain_Battler) == B_SIDE_PLAYER)
+ {
+ objVram = (void*)(OBJ_VRAM0);
+ if (!IsDoubleBattle())
+ objVram += spriteTileNum + 0x820;
+ else
+ objVram += spriteTileNum + 0x420;
+ }
+ else
+ {
+ objVram = (void*)(OBJ_VRAM0);
+ objVram += spriteTileNum + 0x400;
+ }
+ TextIntoHealthboxObject(objVram, windowTileData, 3);
+ RemoveWindowOnHealthbox(windowId);
+}
+
+void UpdateHpTextInHealthbox(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent)
+{
+ u32 windowId, spriteTileNum;
+ u8 *windowTileData;
+ u8 *strptr;
+ void *objVram;
+
+ if (GetBattlerSide(gSprites[healthboxSpriteId].hMain_Battler) == B_SIDE_PLAYER && !IsDoubleBattle())
+ {
+ u8 text[8];
+ if (maxOrCurrent != HP_CURRENT) // singles, max
+ {
+ ConvertIntToDecimalStringN(text, value, STR_CONV_MODE_RIGHT_ALIGN, 3);
+ windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, 0, 5, &windowId);
+ spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum;
+ TextIntoHealthboxObject( (void*)(OBJ_VRAM0) + spriteTileNum * TILE_SIZE_4BPP + 0xA40, windowTileData, 2);
+ RemoveWindowOnHealthbox(windowId);
+ }
+ else // singles, current
+ {
+ strptr = ConvertIntToDecimalStringN(text, value, STR_CONV_MODE_RIGHT_ALIGN, 3);
+ *strptr++ = CHAR_SLASH;
+ *strptr++ = EOS;
+ windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, 4, 5, &windowId);
+ spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum;
+ TextIntoHealthboxObject((void *)(OBJ_VRAM0) + spriteTileNum * TILE_SIZE_4BPP + 0x2E0, windowTileData, 1);
+ TextIntoHealthboxObject((void *)(OBJ_VRAM0) + spriteTileNum * TILE_SIZE_4BPP + 0xA00, windowTileData + 0x20, 2);
+ RemoveWindowOnHealthbox(windowId);
+ }
+ }
+ else
+ {
+ u8 battler;
+
+ u8 text[20] = __("{COLOR 01}{HIGHLIGHT 02}");
+ battler = gSprites[healthboxSpriteId].hMain_Battler;
+ if (IsDoubleBattle() == TRUE || GetBattlerSide(battler) == B_SIDE_OPPONENT)
+ {
+ UpdateHpTextInHealthboxInDoubles(healthboxSpriteId, value, maxOrCurrent);
+ }
+ else
+ {
+ u32 var;
+ u8 i;
+
+ if (GetBattlerSide(gSprites[healthboxSpriteId].data[6]) == B_SIDE_PLAYER)
+ {
+ if (maxOrCurrent == HP_CURRENT)
+ var = 29;
+ else
+ var = 89;
+ }
+ else
+ {
+ if (maxOrCurrent == HP_CURRENT)
+ var = 20;
+ else
+ var = 48;
+ }
+
+ ConvertIntToDecimalStringN(text + 6, value, STR_CONV_MODE_RIGHT_ALIGN, 3);
+ RenderTextFont9(gMonSpritesGfxPtr->barFontGfx, 0, text, 0, 0, 0, 0, 0);
+
+ for (i = 0; i < 3; i++)
+ {
+ CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[i * 64 + 32],
+ (void*)((OBJ_VRAM0) + TILE_SIZE_4BPP * (gSprites[healthboxSpriteId].oam.tileNum + var + i)),
+ 0x20);
+ }
+ }
+ }
+}
+
+static const u8 gUnknown_8260540[] = _("/");
+
+static void UpdateHpTextInHealthboxInDoubles(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent)
+{
+ u32 windowId, spriteTileNum;
+ u8 *windowTileData;
+ void *objVram;
+
+ u8 battlerId;
+
+ u8 text[20] = __("{COLOR 01}{HIGHLIGHT 00}");
+ battlerId = gSprites[healthboxSpriteId].hMain_Battler;
+
+ if (gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars) // don't print text if only bars are visible
+ {
+ u8 var = 4;
+ u8 r7;
+ u8 *txtPtr;
+ u8 i;
+
+ if (maxOrCurrent == HP_CURRENT)
+ var = 0;
+
+ r7 = gSprites[healthboxSpriteId].data[5];
+ txtPtr = ConvertIntToDecimalStringN(text + 6, value, STR_CONV_MODE_RIGHT_ALIGN, 3);
+ if (!maxOrCurrent)
+ StringCopy(txtPtr, gUnknown_8260540);
+ RenderTextFont9(gMonSpritesGfxPtr->barFontGfx, 0, text, 0, 0, 0, 0, 0);
+
+ for (i = var; i < var + 3; i++)
+ {
+ if (i < 3)
+ {
+ CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[((i - var) * 64) + 32],
+ (void*)((OBJ_VRAM0) + 32 * (1 + gSprites[r7].oam.tileNum + i)),
+ 0x20);
+ }
+ else
+ {
+ CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[((i - var) * 64) + 32],
+ (void*)((OBJ_VRAM0 + 0x20) + 32 * (i + gSprites[r7].oam.tileNum)),
+ 0x20);
+ }
+ }
+
+ if (maxOrCurrent == HP_CURRENT)
+ {
+ CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[224],
+ (void*)((OBJ_VRAM0) + ((gSprites[r7].oam.tileNum + 4) * TILE_SIZE_4BPP)),
+ 0x20);
+ CpuFill32(0, (void*)((OBJ_VRAM0) + (gSprites[r7].oam.tileNum * TILE_SIZE_4BPP)), 0x20);
+ }
+ else
+ {
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) // Impossible to reach part, because the battlerId is from the opponent's side.
+ {
+ CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_116),
+ (void*)(OBJ_VRAM0) + ((gSprites[healthboxSpriteId].oam.tileNum + 52) * TILE_SIZE_4BPP),
+ 0x20);
+ }
+ }
+ }
+}
+
+// Prints mon's nature, catch and flee rate. Probably used to test pokeblock-related features.
+static void PrintSafariMonInfo(u8 healthboxSpriteId, struct Pokemon *mon)
+{
+ u8 text[20] = __("{COLOR 01}{HIGHLIGHT 02}");
+ s32 j, spriteTileNum;
+ u8 *barFontGfx;
+ u8 i, var, nature, healthBarSpriteId;
+
+ barFontGfx = &gMonSpritesGfxPtr->barFontGfx[0x520 + (GetBattlerPosition(gSprites[healthboxSpriteId].hMain_Battler) * 384)];
+ var = 5;
+ nature = GetNature(mon);
+ StringCopy(text + 6, gNatureNamePointers[nature]);
+ RenderTextFont9(barFontGfx, 0, text, 0, 0, 0, 0, 0);
+
+ for (j = 6, i = 0; i < var; i++, j++)
+ {
+ u8 elementId;
+
+ if ((text[j] >= 55 && text[j] <= 74) || (text[j] >= 135 && text[j] <= 154))
+ elementId = HEALTHBOX_GFX_44;
+ else if ((text[j] >= 75 && text[j] <= 79) || (text[j] >= 155 && text[j] <= 159))
+ elementId = HEALTHBOX_GFX_45;
+ else
+ elementId = HEALTHBOX_GFX_43;
+
+ CpuCopy32(GetHealthboxElementGfxPtr(elementId), barFontGfx + (i * 64), 0x20);
+ }
+
+ for (j = 1; j < var + 1; j++)
+ {
+ spriteTileNum = (gSprites[healthboxSpriteId].oam.tileNum + (j - (j / 8 * 8)) + (j / 8 * 64)) * TILE_SIZE_4BPP;
+ CpuCopy32(barFontGfx, (void*)(OBJ_VRAM0) + (spriteTileNum), 0x20);
+ barFontGfx += 0x20;
+
+ spriteTileNum = (8 + gSprites[healthboxSpriteId].oam.tileNum + (j - (j / 8 * 8)) + (j / 8 * 64)) * TILE_SIZE_4BPP;
+ CpuCopy32(barFontGfx, (void*)(OBJ_VRAM0) + (spriteTileNum), 0x20);
+ barFontGfx += 0x20;
+ }
+
+ healthBarSpriteId = gSprites[healthboxSpriteId].hMain_HealthBarSpriteId;
+ ConvertIntToDecimalStringN(text + 6, gBattleStruct->safariCatchFactor, STR_CONV_MODE_RIGHT_ALIGN, 2);
+ ConvertIntToDecimalStringN(text + 9, gBattleStruct->safariEscapeFactor, STR_CONV_MODE_RIGHT_ALIGN, 2);
+ text[5] = CHAR_SPACE;
+ text[8] = CHAR_SLASH;
+ RenderTextFont9(gMonSpritesGfxPtr->barFontGfx, 0, text, 0, 0, 0, 0, 0);
+
+ j = healthBarSpriteId; // Needed to match for some reason.
+ for (j = 0; j < 5; j++)
+ {
+ if (j <= 1)
+ {
+ CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[0x40 * j + 0x20],
+ (void*)(OBJ_VRAM0) + (gSprites[healthBarSpriteId].oam.tileNum + 2 + j) * TILE_SIZE_4BPP,
+ 32);
+ }
+ else
+ {
+ CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[0x40 * j + 0x20],
+ (void*)(OBJ_VRAM0 + 0xC0) + (j + gSprites[healthBarSpriteId].oam.tileNum) * TILE_SIZE_4BPP,
+ 32);
+ }
+ }
+}
+
+void SwapHpBarsWithHpText(void)
+{
+ s32 i;
+ u8 healthBarSpriteId;
+
+ for (i = 0; i < gBattlersCount; i++)
+ {
+ if (gSprites[gHealthboxSpriteIds[i]].callback == SpriteCallbackDummy
+ && GetBattlerSide(i) != B_SIDE_OPPONENT
+ && (IsDoubleBattle() || GetBattlerSide(i) != B_SIDE_PLAYER))
+ {
+ bool8 noBars;
+
+ gBattleSpritesDataPtr->battlerData[i].hpNumbersNoBars ^= 1;
+ noBars = gBattleSpritesDataPtr->battlerData[i].hpNumbersNoBars;
+ if (GetBattlerSide(i) == B_SIDE_PLAYER)
+ {
+ if (!IsDoubleBattle())
+ continue;
+ if (gBattleTypeFlags & BATTLE_TYPE_SAFARI)
+ continue;
+
+ if (noBars == TRUE) // bars to text
+ {
+ healthBarSpriteId = gSprites[gHealthboxSpriteIds[i]].hMain_HealthBarSpriteId;
+
+ CpuFill32(0, (void*)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * TILE_SIZE_4BPP), 0x100);
+ UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_HP), HP_CURRENT);
+ UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_MAX_HP), HP_MAX);
+ }
+ else // text to bars
+ {
+ UpdateStatusIconInHealthbox(gHealthboxSpriteIds[i]);
+ UpdateHealthboxAttribute(gHealthboxSpriteIds[i], &gPlayerParty[gBattlerPartyIndexes[i]], HEALTHBOX_HEALTH_BAR);
+ CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_117), (void*)(OBJ_VRAM0 + 0x680 + gSprites[gHealthboxSpriteIds[i]].oam.tileNum * TILE_SIZE_4BPP), 32);
+ }
+ }
+ else
+ {
+ if (noBars == TRUE) // bars to text
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_SAFARI)
+ {
+ // Most likely a debug function.
+ PrintSafariMonInfo(gHealthboxSpriteIds[i], &gEnemyParty[gBattlerPartyIndexes[i]]);
+ }
+ else
+ {
+ healthBarSpriteId = gSprites[gHealthboxSpriteIds[i]].hMain_HealthBarSpriteId;
+
+ CpuFill32(0, (void *)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * 32), 0x100);
+ UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_HP), HP_CURRENT);
+ UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_MAX_HP), HP_MAX);
+ }
+ }
+ else // text to bars
+ {
+ UpdateStatusIconInHealthbox(gHealthboxSpriteIds[i]);
+ UpdateHealthboxAttribute(gHealthboxSpriteIds[i], &gEnemyParty[gBattlerPartyIndexes[i]], HEALTHBOX_HEALTH_BAR);
+ if (gBattleTypeFlags & BATTLE_TYPE_SAFARI)
+ UpdateHealthboxAttribute(gHealthboxSpriteIds[i], &gEnemyParty[gBattlerPartyIndexes[i]], HEALTHBOX_NICK);
+ }
+ }
+ gSprites[gHealthboxSpriteIds[i]].hMain_Data7 ^= 1;
+ }
+ }
+}
+
+#define tBattler data[0]
+#define tSummaryBarSpriteId data[1]
+#define tBallIconSpriteId(n) data[3 + n]
+#define tIsBattleStart data[10]
+#define tData15 data[15]
+
+#ifdef NONMATCHING
+static u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo, u8 arg2, bool8 isBattleStart)
+{
+ bool8 isOpponent;
+ s8 sp14;
+ s16 bar_X, bar_Y, bar_pos2_X, bar_data0;
+ s32 i;
+ u8 summaryBarSpriteId;
+ u8 ballIconSpritesIds[PARTY_SIZE];
+ u8 taskId;
+
+ if (!arg2 || GetBattlerPosition(battlerId) != B_POSITION_OPPONENT_RIGHT)
+ {
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
+ {
+ isOpponent = FALSE;
+ bar_X = 136, bar_Y = 96;
+ bar_pos2_X = 100;
+ bar_data0 = -5;
+ }
+ else
+ {
+ isOpponent = TRUE;
+
+ if (!arg2 || !IsDoubleBattle())
+ bar_X = 104, bar_Y = 40;
+ else
+ bar_X = 104, bar_Y = 16;
+
+ bar_pos2_X = -100;
+ bar_data0 = 5;
+ }
+ }
+ else
+ {
+ isOpponent = TRUE;
+ bar_X = 104, bar_Y = 40;
+ bar_pos2_X = -100;
+ bar_data0 = 5;
+ }
+
+ for (i = 0, sp14 = 0; i < PARTY_SIZE; i++)
+ {
+ if (partyInfo[i].hp != 0xFFFF)
+ sp14++;
+ }
+
+ LoadCompressedSpriteSheetUsingHeap(&sStatusSummaryBarSpriteSheets[isOpponent]);
+ LoadSpriteSheet(&sStatusSummaryBallsSpriteSheets[isOpponent]);
+ LoadSpritePalette(&sStatusSummaryBarSpritePals[isOpponent]);
+ LoadSpritePalette(&sStatusSummaryBallsSpritePals[isOpponent]);
+
+ summaryBarSpriteId = CreateSprite(&sStatusSummaryBarSpriteTemplates[isOpponent], bar_X, bar_Y, 10);
+ SetSubspriteTables(&gSprites[summaryBarSpriteId], sStatusSummaryBar_SubspriteTable);
+ gSprites[summaryBarSpriteId].pos2.x = bar_pos2_X;
+ gSprites[summaryBarSpriteId].data[0] = bar_data0;
+
+ if (isOpponent)
+ {
+ gSprites[summaryBarSpriteId].pos1.x -= 96;
+ gSprites[summaryBarSpriteId].oam.matrixNum = ST_OAM_HFLIP;
+ }
+ else
+ {
+ gSprites[summaryBarSpriteId].pos1.x += 96;
+ }
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ ballIconSpritesIds[i] = CreateSpriteAtEnd(&sStatusSummaryBallsSpriteTemplates[isOpponent], bar_X, bar_Y - 4, 9);
+
+ if (!isBattleStart)
+ gSprites[ballIconSpritesIds[i]].callback = SpriteCB_StatusSummaryBallsOnSwitchout;
+
+ if (!isOpponent)
+ {
+ gSprites[ballIconSpritesIds[i]].pos2.x = 0;
+ gSprites[ballIconSpritesIds[i]].pos2.y = 0;
+ }
+
+ gSprites[ballIconSpritesIds[i]].data[0] = summaryBarSpriteId;
+
+ if (!isOpponent)
+ {
+ gSprites[ballIconSpritesIds[i]].pos1.x += 10 * i + 24;
+ gSprites[ballIconSpritesIds[i]].data[1] = i * 7 + 10;
+ gSprites[ballIconSpritesIds[i]].pos2.x = 120;
+ }
+ else
+ {
+ gSprites[ballIconSpritesIds[i]].pos1.x -= 10 * (5 - i) + 24;
+ gSprites[ballIconSpritesIds[i]].data[1] = (6 - i) * 7 + 10;
+ gSprites[ballIconSpritesIds[i]].pos2.x = -120;
+ }
+
+ gSprites[ballIconSpritesIds[i]].data[2] = isOpponent;
+ }
+
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
+ {
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
+ {
+ if (partyInfo[i].hp == 0xFFFF) // empty slot or an egg
+ {
+ gSprites[ballIconSpritesIds[i]].oam.tileNum += 1;
+ gSprites[ballIconSpritesIds[i]].data[7] = 1;
+ }
+ else if (partyInfo[i].hp == 0) // fainted mon
+ {
+ gSprites[ballIconSpritesIds[i]].oam.tileNum += 3;
+ }
+ else if (partyInfo[i].status != 0) // mon with major status
+ {
+ gSprites[ballIconSpritesIds[i]].oam.tileNum += 2;
+ }
+ }
+ else
+ {
+ if (i >= sp14) // empty slot or an egg
+ {
+ gSprites[ballIconSpritesIds[i]].oam.tileNum += 1;
+ gSprites[ballIconSpritesIds[i]].data[7] = 1;
+ }
+ else if (partyInfo[i].hp == 0) // fainted mon
+ {
+ gSprites[ballIconSpritesIds[i]].oam.tileNum += 3;
+ }
+ else if (partyInfo[i].status != 0) // mon with major status
+ {
+ gSprites[ballIconSpritesIds[i]].oam.tileNum += 2;
+ }
+ }
+ }
+ }
+ else
+ {
+ /*
+ * FIXME: r4 and r5 are loaded correctly but in the wrong
+ * order.
+ */
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
+ {
+ if (partyInfo[i].hp == 0xFFFF) // empty slot or an egg
+ {
+ gSprites[ballIconSpritesIds[5 - i]].oam.tileNum += 1;
+ gSprites[ballIconSpritesIds[5 - i]].data[7] = 1;
+ }
+ else if (partyInfo[i].hp == 0) // fainted mon
+ {
+ gSprites[ballIconSpritesIds[5 - i]].oam.tileNum += 3;
+ }
+ else if (partyInfo[i].status != 0) // mon with major status
+ {
+ gSprites[ballIconSpritesIds[5 - i]].oam.tileNum += 2;
+ }
+ }
+ else
+ {
+ if (i >= sp14) // empty slot or an egg
+ {
+ gSprites[ballIconSpritesIds[5 - i]].oam.tileNum += 1;
+ gSprites[ballIconSpritesIds[5 - i]].data[7] = 1;
+ }
+ else if (partyInfo[i].hp == 0) // fainted mon
+ {
+ gSprites[ballIconSpritesIds[5 - i]].oam.tileNum += 3;
+ }
+ else if (partyInfo[i].status != 0) // mon with major status
+ {
+ gSprites[ballIconSpritesIds[5 - i]].oam.tileNum += 2;
+ }
+ }
+ }
+ }
+
+ taskId = CreateTask(TaskDummy, 5);
+ gTasks[taskId].tBattler = battlerId;
+ gTasks[taskId].tSummaryBarSpriteId = summaryBarSpriteId;
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ gTasks[taskId].tBallIconSpriteId(i) = ballIconSpritesIds[i];
+
+ gTasks[taskId].tIsBattleStart = isBattleStart;
+ PlaySE12WithPanning(SE_TB_START, 0);
+ return taskId;
+}
+#else
+NAKED
+u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo, u8 arg2, bool8 isBattleStart)
+{
+ asm_unified("\tpush {r4-r7,lr}\n"
+ "\tmov r7, r10\n"
+ "\tmov r6, r9\n"
+ "\tmov r5, r8\n"
+ "\tpush {r5-r7}\n"
+ "\tsub sp, 0x28\n"
+ "\tstr r1, [sp, 0xC]\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tstr r0, [sp, 0x8]\n"
+ "\tlsls r2, 24\n"
+ "\tlsrs r2, 24\n"
+ "\tadds r4, r2, 0\n"
+ "\tlsls r3, 24\n"
+ "\tlsrs r3, 24\n"
+ "\tstr r3, [sp, 0x10]\n"
+ "\tcmp r4, 0\n"
+ "\tbeq _08048D44\n"
+ "\tbl GetBattlerPosition\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tcmp r0, 0x3\n"
+ "\tbeq _08048D88\n"
+ "_08048D44:\n"
+ "\tldr r0, [sp, 0x8]\n"
+ "\tbl GetBattlerSide\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbne _08048D64\n"
+ "\tmovs r7, 0\n"
+ "\tmovs r1, 0x88\n"
+ "\tmovs r2, 0x60\n"
+ "\tmovs r0, 0x64\n"
+ "\tmov r8, r0\n"
+ "\tldr r5, _08048D60 @ =0x0000fffb\n"
+ "\tb _08048D94\n"
+ "\t.align 2, 0\n"
+ "_08048D60: .4byte 0x0000fffb\n"
+ "_08048D64:\n"
+ "\tmovs r7, 0x1\n"
+ "\tcmp r4, 0\n"
+ "\tbeq _08048D74\n"
+ "\tbl IsDoubleBattle\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbne _08048D7A\n"
+ "_08048D74:\n"
+ "\tmovs r1, 0x68\n"
+ "\tmovs r2, 0x28\n"
+ "\tb _08048D7E\n"
+ "_08048D7A:\n"
+ "\tmovs r1, 0x68\n"
+ "\tmovs r2, 0x10\n"
+ "_08048D7E:\n"
+ "\tldr r3, _08048D84 @ =0x0000ff9c\n"
+ "\tmov r8, r3\n"
+ "\tb _08048D92\n"
+ "\t.align 2, 0\n"
+ "_08048D84: .4byte 0x0000ff9c\n"
+ "_08048D88:\n"
+ "\tmovs r7, 0x1\n"
+ "\tmovs r1, 0x68\n"
+ "\tmovs r2, 0x28\n"
+ "\tldr r5, _08048E40 @ =0x0000ff9c\n"
+ "\tmov r8, r5\n"
+ "_08048D92:\n"
+ "\tmovs r5, 0x5\n"
+ "_08048D94:\n"
+ "\tmovs r6, 0\n"
+ "\tstr r6, [sp, 0x14]\n"
+ "\tlsls r4, r7, 3\n"
+ "\tldr r0, _08048E44 @ =sStatusSummaryBarSpriteSheets\n"
+ "\tmov r10, r0\n"
+ "\tlsls r3, r7, 1\n"
+ "\tmov r9, r3\n"
+ "\tlsls r1, 16\n"
+ "\tstr r1, [sp, 0x20]\n"
+ "\tlsls r2, 16\n"
+ "\tstr r2, [sp, 0x24]\n"
+ "\tldr r2, _08048E48 @ =0x0000ffff\n"
+ "\tldr r1, [sp, 0xC]\n"
+ "\tmovs r6, 0x5\n"
+ "_08048DB0:\n"
+ "\tldrh r0, [r1]\n"
+ "\tcmp r0, r2\n"
+ "\tbeq _08048DC4\n"
+ "\tldr r3, [sp, 0x14]\n"
+ "\tlsls r0, r3, 24\n"
+ "\tmovs r3, 0x80\n"
+ "\tlsls r3, 17\n"
+ "\tadds r0, r3\n"
+ "\tlsrs r0, 24\n"
+ "\tstr r0, [sp, 0x14]\n"
+ "_08048DC4:\n"
+ "\tadds r1, 0x8\n"
+ "\tsubs r6, 0x1\n"
+ "\tcmp r6, 0\n"
+ "\tbge _08048DB0\n"
+ "\tmov r6, r10\n"
+ "\tadds r0, r4, r6\n"
+ "\tbl LoadCompressedSpriteSheetUsingHeap\n"
+ "\tldr r0, _08048E4C @ =sStatusSummaryBallsSpriteSheets\n"
+ "\tadds r0, r4, r0\n"
+ "\tbl LoadSpriteSheet\n"
+ "\tldr r0, _08048E50 @ =sStatusSummaryBarSpritePals\n"
+ "\tadds r0, r4, r0\n"
+ "\tbl LoadSpritePalette\n"
+ "\tldr r0, _08048E54 @ =sStatusSummaryBallsSpritePals\n"
+ "\tadds r0, r4, r0\n"
+ "\tbl LoadSpritePalette\n"
+ "\tmov r1, r9\n"
+ "\tadds r0, r1, r7\n"
+ "\tlsls r0, 3\n"
+ "\tldr r1, _08048E58 @ =sStatusSummaryBarSpriteTemplates\n"
+ "\tadds r0, r1\n"
+ "\tldr r2, [sp, 0x20]\n"
+ "\tasrs r1, r2, 16\n"
+ "\tldr r3, [sp, 0x24]\n"
+ "\tasrs r2, r3, 16\n"
+ "\tmovs r3, 0xA\n"
+ "\tbl CreateSprite\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tstr r0, [sp, 0x18]\n"
+ "\tlsls r0, 4\n"
+ "\tldr r6, [sp, 0x18]\n"
+ "\tadds r0, r6\n"
+ "\tlsls r0, 2\n"
+ "\tldr r1, _08048E5C @ =gSprites\n"
+ "\tadds r4, r0, r1\n"
+ "\tldr r1, _08048E60 @ =sStatusSummaryBar_SubspriteTable\n"
+ "\tadds r0, r4, 0\n"
+ "\tbl SetSubspriteTables\n"
+ "\tmov r0, r8\n"
+ "\tstrh r0, [r4, 0x24]\n"
+ "\tstrh r5, [r4, 0x2E]\n"
+ "\tcmp r7, 0\n"
+ "\tbeq _08048E64\n"
+ "\tldrh r0, [r4, 0x20]\n"
+ "\tsubs r0, 0x60\n"
+ "\tstrh r0, [r4, 0x20]\n"
+ "\tldrb r1, [r4, 0x3]\n"
+ "\tmovs r0, 0x3F\n"
+ "\tnegs r0, r0\n"
+ "\tands r0, r1\n"
+ "\tmovs r1, 0x10\n"
+ "\torrs r0, r1\n"
+ "\tstrb r0, [r4, 0x3]\n"
+ "\tb _08048E6A\n"
+ "\t.align 2, 0\n"
+ "_08048E40: .4byte 0x0000ff9c\n"
+ "_08048E44: .4byte sStatusSummaryBarSpriteSheets\n"
+ "_08048E48: .4byte 0x0000ffff\n"
+ "_08048E4C: .4byte sStatusSummaryBallsSpriteSheets\n"
+ "_08048E50: .4byte sStatusSummaryBarSpritePals\n"
+ "_08048E54: .4byte sStatusSummaryBallsSpritePals\n"
+ "_08048E58: .4byte sStatusSummaryBarSpriteTemplates\n"
+ "_08048E5C: .4byte gSprites\n"
+ "_08048E60: .4byte sStatusSummaryBar_SubspriteTable\n"
+ "_08048E64:\n"
+ "\tldrh r0, [r4, 0x20]\n"
+ "\tadds r0, 0x60\n"
+ "\tstrh r0, [r4, 0x20]\n"
+ "_08048E6A:\n"
+ "\tmovs r6, 0\n"
+ "\tldr r1, _08048F14 @ =gSprites\n"
+ "\tmov r10, r1\n"
+ "\tmov r4, sp\n"
+ "\tmov r2, r9\n"
+ "\tadds r0, r2, r7\n"
+ "\tlsls r0, 3\n"
+ "\tstr r0, [sp, 0x1C]\n"
+ "\tmovs r3, 0xA\n"
+ "\tmov r9, r3\n"
+ "\tmov r8, r6\n"
+ "_08048E80:\n"
+ "\tldr r0, _08048F18 @ =sStatusSummaryBallsSpriteTemplates\n"
+ "\tldr r5, [sp, 0x24]\n"
+ "\tldr r1, _08048F1C @ =0xfffc0000\n"
+ "\tadds r2, r5, r1\n"
+ "\tldr r3, [sp, 0x1C]\n"
+ "\tadds r0, r3, r0\n"
+ "\tldr r5, [sp, 0x20]\n"
+ "\tasrs r1, r5, 16\n"
+ "\tasrs r2, 16\n"
+ "\tmovs r3, 0x9\n"
+ "\tbl CreateSpriteAtEnd\n"
+ "\tstrb r0, [r4]\n"
+ "\tldr r0, [sp, 0x10]\n"
+ "\tcmp r0, 0\n"
+ "\tbne _08048EB0\n"
+ "\tldrb r0, [r4]\n"
+ "\tlsls r1, r0, 4\n"
+ "\tadds r1, r0\n"
+ "\tlsls r1, 2\n"
+ "\tldr r2, _08048F20 @ =gSprites + 0x1C\n"
+ "\tadds r1, r2\n"
+ "\tldr r0, _08048F24 @ =SpriteCB_StatusSummaryBallsOnSwitchout\n"
+ "\tstr r0, [r1]\n"
+ "_08048EB0:\n"
+ "\tldr r5, _08048F14 @ =gSprites\n"
+ "\tcmp r7, 0\n"
+ "\tbne _08048ECE\n"
+ "\tldrb r1, [r4]\n"
+ "\tlsls r0, r1, 4\n"
+ "\tadds r0, r1\n"
+ "\tlsls r0, 2\n"
+ "\tadd r0, r10\n"
+ "\tstrh r7, [r0, 0x24]\n"
+ "\tldrb r1, [r4]\n"
+ "\tlsls r0, r1, 4\n"
+ "\tadds r0, r1\n"
+ "\tlsls r0, 2\n"
+ "\tadd r0, r10\n"
+ "\tstrh r7, [r0, 0x26]\n"
+ "_08048ECE:\n"
+ "\tldrb r1, [r4]\n"
+ "\tlsls r0, r1, 4\n"
+ "\tadds r0, r1\n"
+ "\tlsls r0, 2\n"
+ "\tadds r0, r5\n"
+ "\tmovs r1, 0\n"
+ "\tmov r3, sp\n"
+ "\tldrh r3, [r3, 0x18]\n"
+ "\tstrh r3, [r0, 0x2E]\n"
+ "\tcmp r7, 0\n"
+ "\tbne _08048F28\n"
+ "\tldrb r0, [r4]\n"
+ "\tlsls r1, r0, 4\n"
+ "\tadds r1, r0\n"
+ "\tlsls r1, 2\n"
+ "\tadds r1, r5\n"
+ "\tldrh r0, [r1, 0x20]\n"
+ "\tadds r0, 0x18\n"
+ "\tadd r0, r8\n"
+ "\tstrh r0, [r1, 0x20]\n"
+ "\tldrb r1, [r4]\n"
+ "\tlsls r0, r1, 4\n"
+ "\tadds r0, r1\n"
+ "\tlsls r0, 2\n"
+ "\tadds r0, r5\n"
+ "\tmov r1, r9\n"
+ "\tstrh r1, [r0, 0x30]\n"
+ "\tldrb r1, [r4]\n"
+ "\tlsls r0, r1, 4\n"
+ "\tadds r0, r1\n"
+ "\tlsls r0, 2\n"
+ "\tadds r0, r5\n"
+ "\tmovs r1, 0x78\n"
+ "\tb _08048F66\n"
+ "\t.align 2, 0\n"
+ "_08048F14: .4byte gSprites\n"
+ "_08048F18: .4byte sStatusSummaryBallsSpriteTemplates\n"
+ "_08048F1C: .4byte 0xfffc0000\n"
+ "_08048F20: .4byte gSprites + 0x1C\n"
+ "_08048F24: .4byte SpriteCB_StatusSummaryBallsOnSwitchout\n"
+ "_08048F28:\n"
+ "\tldrb r0, [r4]\n"
+ "\tlsls r2, r0, 4\n"
+ "\tadds r2, r0\n"
+ "\tlsls r2, 2\n"
+ "\tadds r2, r5\n"
+ "\tldrh r3, [r2, 0x20]\n"
+ "\tsubs r3, 0x18\n"
+ "\tmovs r1, 0x5\n"
+ "\tsubs r1, r6\n"
+ "\tlsls r0, r1, 2\n"
+ "\tadds r0, r1\n"
+ "\tlsls r0, 1\n"
+ "\tsubs r3, r0\n"
+ "\tstrh r3, [r2, 0x20]\n"
+ "\tldrb r0, [r4]\n"
+ "\tlsls r2, r0, 4\n"
+ "\tadds r2, r0\n"
+ "\tlsls r2, 2\n"
+ "\tadds r2, r5\n"
+ "\tmovs r1, 0x6\n"
+ "\tsubs r1, r6\n"
+ "\tlsls r0, r1, 3\n"
+ "\tsubs r0, r1\n"
+ "\tadds r0, 0xA\n"
+ "\tstrh r0, [r2, 0x30]\n"
+ "\tldrb r1, [r4]\n"
+ "\tlsls r0, r1, 4\n"
+ "\tadds r0, r1\n"
+ "\tlsls r0, 2\n"
+ "\tadds r0, r5\n"
+ "\tldr r1, _08048FD4 @ =0x0000ff88\n"
+ "_08048F66:\n"
+ "\tstrh r1, [r0, 0x24]\n"
+ "\tldrb r1, [r4]\n"
+ "\tlsls r0, r1, 4\n"
+ "\tadds r0, r1\n"
+ "\tlsls r0, 2\n"
+ "\tadds r0, r5\n"
+ "\tstrh r7, [r0, 0x32]\n"
+ "\tadds r4, 0x1\n"
+ "\tmovs r2, 0x7\n"
+ "\tadd r9, r2\n"
+ "\tmovs r3, 0xA\n"
+ "\tadd r8, r3\n"
+ "\tadds r6, 0x1\n"
+ "\tcmp r6, 0x5\n"
+ "\tbgt _08048F86\n"
+ "\tb _08048E80\n"
+ "_08048F86:\n"
+ "\tldr r0, [sp, 0x8]\n"
+ "\tbl GetBattlerSide\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbne _0804906E\n"
+ "\tmovs r6, 0\n"
+ "\tldr r5, _08048FD8 @ =gBattleTypeFlags\n"
+ "\tmov r10, r5\n"
+ "\tldr r0, _08048FDC @ =0x0000ffff\n"
+ "\tmov r9, r0\n"
+ "\tldr r7, _08048FE0 @ =gSprites\n"
+ "\tldr r1, _08048FE4 @ =0x000003ff\n"
+ "\tmov r12, r1\n"
+ "\tldr r2, _08048FE8 @ =0xfffffc00\n"
+ "\tmov r8, r2\n"
+ "\tmov r4, sp\n"
+ "\tldr r5, [sp, 0xC]\n"
+ "_08048FAA:\n"
+ "\tmov r3, r10\n"
+ "\tldr r0, [r3]\n"
+ "\tmovs r1, 0x40\n"
+ "\tands r0, r1\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _08048FEC\n"
+ "\tldrh r0, [r5]\n"
+ "\tcmp r0, r9\n"
+ "\tbeq _08048FF6\n"
+ "\tcmp r0, 0\n"
+ "\tbne _0804903E\n"
+ "\tldrb r0, [r4]\n"
+ "\tlsls r2, r0, 4\n"
+ "\tadds r2, r0\n"
+ "\tlsls r2, 2\n"
+ "\tadds r2, r7\n"
+ "\tldrh r3, [r2, 0x4]\n"
+ "\tlsls r1, r3, 22\n"
+ "\tlsrs r1, 22\n"
+ "\tadds r1, 0x3\n"
+ "\tb _08049056\n"
+ "\t.align 2, 0\n"
+ "_08048FD4: .4byte 0x0000ff88\n"
+ "_08048FD8: .4byte gBattleTypeFlags\n"
+ "_08048FDC: .4byte 0x0000ffff\n"
+ "_08048FE0: .4byte gSprites\n"
+ "_08048FE4: .4byte 0x000003ff\n"
+ "_08048FE8: .4byte 0xfffffc00\n"
+ "_08048FEC:\n"
+ "\tldr r1, [sp, 0x14]\n"
+ "\tlsls r0, r1, 24\n"
+ "\tasrs r0, 24\n"
+ "\tcmp r6, r0\n"
+ "\tblt _08049024\n"
+ "_08048FF6:\n"
+ "\tldrb r0, [r4]\n"
+ "\tlsls r2, r0, 4\n"
+ "\tadds r2, r0\n"
+ "\tlsls r2, 2\n"
+ "\tadds r2, r7\n"
+ "\tldrh r3, [r2, 0x4]\n"
+ "\tlsls r1, r3, 22\n"
+ "\tlsrs r1, 22\n"
+ "\tadds r1, 0x1\n"
+ "\tmov r0, r12\n"
+ "\tands r1, r0\n"
+ "\tmov r0, r8\n"
+ "\tands r0, r3\n"
+ "\torrs r0, r1\n"
+ "\tstrh r0, [r2, 0x4]\n"
+ "\tldrb r1, [r4]\n"
+ "\tlsls r0, r1, 4\n"
+ "\tadds r0, r1\n"
+ "\tlsls r0, 2\n"
+ "\tadds r0, r7\n"
+ "\tmovs r1, 0x1\n"
+ "\tstrh r1, [r0, 0x3C]\n"
+ "\tb _08049062\n"
+ "_08049024:\n"
+ "\tldrh r0, [r5]\n"
+ "\tcmp r0, 0\n"
+ "\tbne _0804903E\n"
+ "\tldrb r0, [r4]\n"
+ "\tlsls r2, r0, 4\n"
+ "\tadds r2, r0\n"
+ "\tlsls r2, 2\n"
+ "\tadds r2, r7\n"
+ "\tldrh r3, [r2, 0x4]\n"
+ "\tlsls r1, r3, 22\n"
+ "\tlsrs r1, 22\n"
+ "\tadds r1, 0x3\n"
+ "\tb _08049056\n"
+ "_0804903E:\n"
+ "\tldr r0, [r5, 0x4]\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _08049062\n"
+ "\tldrb r0, [r4]\n"
+ "\tlsls r2, r0, 4\n"
+ "\tadds r2, r0\n"
+ "\tlsls r2, 2\n"
+ "\tadds r2, r7\n"
+ "\tldrh r3, [r2, 0x4]\n"
+ "\tlsls r1, r3, 22\n"
+ "\tlsrs r1, 22\n"
+ "\tadds r1, 0x2\n"
+ "_08049056:\n"
+ "\tmov r0, r12\n"
+ "\tands r1, r0\n"
+ "\tmov r0, r8\n"
+ "\tands r0, r3\n"
+ "\torrs r0, r1\n"
+ "\tstrh r0, [r2, 0x4]\n"
+ "_08049062:\n"
+ "\tadds r4, 0x1\n"
+ "\tadds r5, 0x8\n"
+ "\tadds r6, 0x1\n"
+ "\tcmp r6, 0x5\n"
+ "\tble _08048FAA\n"
+ "\tb _08049148\n"
+ "_0804906E:\n"
+ "\tmovs r6, 0\n"
+ "\tldr r1, _080490B4 @ =gBattleTypeFlags\n"
+ "\tmov r10, r1\n"
+ "\tldr r2, _080490B8 @ =0x0000ffff\n"
+ "\tmov r9, r2\n"
+ "\tldr r7, _080490BC @ =gSprites\n"
+ "\tldr r3, _080490C0 @ =0x000003ff\n"
+ "\tmov r12, r3\n"
+ "\tldr r5, _080490C4 @ =0xfffffc00\n"
+ "\tmov r8, r5\n"
+ "\tldr r5, [sp, 0xC]\n"
+ "\tmov r4, sp\n"
+ "\tadds r4, 0x5\n"
+ "_08049088:\n"
+ "\tmov r1, r10\n"
+ "\tldr r0, [r1]\n"
+ "\tmovs r1, 0x40\n"
+ "\tands r0, r1\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _080490C8\n"
+ "\tldrh r0, [r5]\n"
+ "\tcmp r0, r9\n"
+ "\tbeq _080490D2\n"
+ "\tcmp r0, 0\n"
+ "\tbne _0804911A\n"
+ "\tldrb r0, [r4]\n"
+ "\tlsls r2, r0, 4\n"
+ "\tadds r2, r0\n"
+ "\tlsls r2, 2\n"
+ "\tadds r2, r7\n"
+ "\tldrh r3, [r2, 0x4]\n"
+ "\tlsls r1, r3, 22\n"
+ "\tlsrs r1, 22\n"
+ "\tadds r1, 0x3\n"
+ "\tb _08049132\n"
+ "\t.align 2, 0\n"
+ "_080490B4: .4byte gBattleTypeFlags\n"
+ "_080490B8: .4byte 0x0000ffff\n"
+ "_080490BC: .4byte gSprites\n"
+ "_080490C0: .4byte 0x000003ff\n"
+ "_080490C4: .4byte 0xfffffc00\n"
+ "_080490C8:\n"
+ "\tldr r1, [sp, 0x14]\n"
+ "\tlsls r0, r1, 24\n"
+ "\tasrs r0, 24\n"
+ "\tcmp r6, r0\n"
+ "\tblt _08049100\n"
+ "_080490D2:\n"
+ "\tldrb r0, [r4]\n"
+ "\tlsls r2, r0, 4\n"
+ "\tadds r2, r0\n"
+ "\tlsls r2, 2\n"
+ "\tadds r2, r7\n"
+ "\tldrh r3, [r2, 0x4]\n"
+ "\tlsls r1, r3, 22\n"
+ "\tlsrs r1, 22\n"
+ "\tadds r1, 0x1\n"
+ "\tmov r0, r12\n"
+ "\tands r1, r0\n"
+ "\tmov r0, r8\n"
+ "\tands r0, r3\n"
+ "\torrs r0, r1\n"
+ "\tstrh r0, [r2, 0x4]\n"
+ "\tldrb r1, [r4]\n"
+ "\tlsls r0, r1, 4\n"
+ "\tadds r0, r1\n"
+ "\tlsls r0, 2\n"
+ "\tadds r0, r7\n"
+ "\tmovs r1, 0x1\n"
+ "\tstrh r1, [r0, 0x3C]\n"
+ "\tb _0804913E\n"
+ "_08049100:\n"
+ "\tldrh r0, [r5]\n"
+ "\tcmp r0, 0\n"
+ "\tbne _0804911A\n"
+ "\tldrb r0, [r4]\n"
+ "\tlsls r2, r0, 4\n"
+ "\tadds r2, r0\n"
+ "\tlsls r2, 2\n"
+ "\tadds r2, r7\n"
+ "\tldrh r3, [r2, 0x4]\n"
+ "\tlsls r1, r3, 22\n"
+ "\tlsrs r1, 22\n"
+ "\tadds r1, 0x3\n"
+ "\tb _08049132\n"
+ "_0804911A:\n"
+ "\tldr r0, [r5, 0x4]\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _0804913E\n"
+ "\tldrb r0, [r4]\n"
+ "\tlsls r2, r0, 4\n"
+ "\tadds r2, r0\n"
+ "\tlsls r2, 2\n"
+ "\tadds r2, r7\n"
+ "\tldrh r3, [r2, 0x4]\n"
+ "\tlsls r1, r3, 22\n"
+ "\tlsrs r1, 22\n"
+ "\tadds r1, 0x2\n"
+ "_08049132:\n"
+ "\tmov r0, r12\n"
+ "\tands r1, r0\n"
+ "\tmov r0, r8\n"
+ "\tands r0, r3\n"
+ "\torrs r0, r1\n"
+ "\tstrh r0, [r2, 0x4]\n"
+ "_0804913E:\n"
+ "\tsubs r4, 0x1\n"
+ "\tadds r5, 0x8\n"
+ "\tadds r6, 0x1\n"
+ "\tcmp r6, 0x5\n"
+ "\tble _08049088\n"
+ "_08049148:\n"
+ "\tldr r0, _080491A8 @ =TaskDummy\n"
+ "\tmovs r1, 0x5\n"
+ "\tbl CreateTask\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r4, r0, 24\n"
+ "\tldr r2, _080491AC @ =gTasks\n"
+ "\tlsls r3, r4, 2\n"
+ "\tadds r1, r3, r4\n"
+ "\tlsls r1, 3\n"
+ "\tadds r0, r1, r2\n"
+ "\tmov r5, sp\n"
+ "\tldrh r5, [r5, 0x8]\n"
+ "\tstrh r5, [r0, 0x8]\n"
+ "\tmov r6, sp\n"
+ "\tldrh r6, [r6, 0x18]\n"
+ "\tstrh r6, [r0, 0xA]\n"
+ "\tmovs r6, 0\n"
+ "\tadds r0, r2, 0\n"
+ "\tadds r0, 0xE\n"
+ "\tadds r1, r0\n"
+ "_08049172:\n"
+ "\tmov r5, sp\n"
+ "\tadds r0, r5, r6\n"
+ "\tldrb r0, [r0]\n"
+ "\tstrh r0, [r1]\n"
+ "\tadds r1, 0x2\n"
+ "\tadds r6, 0x1\n"
+ "\tcmp r6, 0x5\n"
+ "\tble _08049172\n"
+ "\tadds r0, r3, r4\n"
+ "\tlsls r0, 3\n"
+ "\tadds r0, r2\n"
+ "\tldrh r6, [r5, 0x10]\n"
+ "\tstrh r6, [r0, 0x1C]\n"
+ "\tmovs r0, 0x6B\n"
+ "\tmovs r1, 0\n"
+ "\tbl PlaySE12WithPanning\n"
+ "\tadds r0, r4, 0\n"
+ "\tadd sp, 0x28\n"
+ "\tpop {r3-r5}\n"
+ "\tmov r8, r3\n"
+ "\tmov r9, r4\n"
+ "\tmov r10, r5\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r1}\n"
+ "\tbx r1\n"
+ "\t.align 2, 0\n"
+ "_080491A8: .4byte TaskDummy\n"
+ "_080491AC: .4byte gTasks");
+}
+#endif //NONMATCHING
+
+void Task_HidePartyStatusSummary(u8 taskId)
+{
+ u8 ballIconSpriteIds[PARTY_SIZE];
+ bool8 isBattleStart;
+ u8 summaryBarSpriteId;
+ u8 battlerId;
+ s32 i;
+
+ isBattleStart = gTasks[taskId].tIsBattleStart;
+ summaryBarSpriteId = gTasks[taskId].tSummaryBarSpriteId;
+ battlerId = gTasks[taskId].tBattler;
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ ballIconSpriteIds[i] = gTasks[taskId].tBallIconSpriteId(i);
+
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0));
+
+ gTasks[taskId].tData15 = 16;
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ gSprites[ballIconSpriteIds[i]].oam.objMode = ST_OAM_OBJ_BLEND;
+
+ gSprites[summaryBarSpriteId].oam.objMode = ST_OAM_OBJ_BLEND;
+
+ if (isBattleStart)
+ {
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
+ {
+ gSprites[ballIconSpriteIds[5 - i]].data[1] = 7 * i;
+ gSprites[ballIconSpriteIds[5 - i]].data[3] = 0;
+ gSprites[ballIconSpriteIds[5 - i]].data[4] = 0;
+ gSprites[ballIconSpriteIds[5 - i]].callback = sub_8049630;
+ }
+ else
+ {
+ gSprites[ballIconSpriteIds[i]].data[1] = 7 * i;
+ gSprites[ballIconSpriteIds[i]].data[3] = 0;
+ gSprites[ballIconSpriteIds[i]].data[4] = 0;
+ gSprites[ballIconSpriteIds[i]].callback = sub_8049630;
+ }
+ }
+ gSprites[summaryBarSpriteId].data[0] /= 2;
+ gSprites[summaryBarSpriteId].data[1] = 0;
+ gSprites[summaryBarSpriteId].callback = sub_8049568;
+ SetSubspriteTables(&gSprites[summaryBarSpriteId], gUnknown_8260404);
+ gTasks[taskId].func = sub_8049388;
+ }
+ else
+ {
+ gTasks[taskId].func = sub_804948C;
+ }
+}
+
+static void sub_8049388(u8 taskId)
+{
+ if ((gTasks[taskId].data[11]++ % 2) == 0)
+ {
+ if (--gTasks[taskId].tData15 < 0)
+ return;
+
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[15], 16 - gTasks[taskId].data[15]));
+ }
+ if (gTasks[taskId].tData15 == 0)
+ gTasks[taskId].func = sub_80493E4;
+}
+
+static void sub_80493E4(u8 taskId)
+{
+ u8 ballIconSpriteIds[PARTY_SIZE];
+ s32 i;
+
+ u8 battlerId = gTasks[taskId].tBattler;
+ if (--gTasks[taskId].tData15 == -1)
+ {
+ u8 summaryBarSpriteId = gTasks[taskId].tSummaryBarSpriteId;
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ ballIconSpriteIds[i] = gTasks[taskId].tBallIconSpriteId(i);
+
+ DestroySpriteAndFreeResources(&gSprites[summaryBarSpriteId]);
+ DestroySpriteAndFreeResources(&gSprites[ballIconSpriteIds[0]]);
+
+ for (i = 1; i < PARTY_SIZE; i++)
+ DestroySprite(&gSprites[ballIconSpriteIds[i]]);
+ }
+ else if (gTasks[taskId].tData15 == -3)
+ {
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ DestroyTask(taskId);
+ }
+}
+
+static void sub_804948C(u8 taskId)
+{
+ u8 ballIconSpriteIds[PARTY_SIZE];
+ s32 i;
+ u8 battlerId = gTasks[taskId].tBattler;
+
+ if (--gTasks[taskId].tData15 >= 0)
+ {
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[15], 16 - gTasks[taskId].data[15]));
+ }
+ else if (gTasks[taskId].tData15 == -1)
+ {
+ u8 summaryBarSpriteId = gTasks[taskId].tSummaryBarSpriteId;
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ ballIconSpriteIds[i] = gTasks[taskId].tBallIconSpriteId(i);
+
+ DestroySpriteAndFreeResources(&gSprites[summaryBarSpriteId]);
+ DestroySpriteAndFreeResources(&gSprites[ballIconSpriteIds[0]]);
+
+ for (i = 1; i < PARTY_SIZE; i++)
+ DestroySprite(&gSprites[ballIconSpriteIds[i]]);
+ }
+ else if (gTasks[taskId].tData15 == -3)
+ {
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ DestroyTask(taskId);
+ }
+}
+
+#undef tBattler
+#undef tSummaryBarSpriteId
+#undef tBallIconSpriteId
+#undef tIsBattleStart
+#undef tData15
+
+static void SpriteCB_StatusSummaryBar(struct Sprite *sprite)
+{
+ if (sprite->pos2.x != 0)
+ sprite->pos2.x += sprite->data[0];
+}
+
+static void sub_8049568(struct Sprite *sprite)
+{
+ sprite->data[1] += 32;
+ if (sprite->data[0] > 0)
+ sprite->pos2.x += sprite->data[1] >> 4;
+ else
+ sprite->pos2.x -= sprite->data[1] >> 4;
+ sprite->data[1] &= 0xF;
+}
+
+static void SpriteCB_StatusSummaryBallsOnBattleStart(struct Sprite *sprite)
+{
+ u8 var1;
+ u16 var2;
+ s8 pan;
+
+ if (sprite->data[1] > 0)
+ {
+ sprite->data[1]--;
+ return;
+ }
+
+ var1 = sprite->data[2];
+ var2 = sprite->data[3];
+ var2 += 56;
+ sprite->data[3] = var2 & 0xFFF0;
+
+ if (var1 != 0)
+ {
+ sprite->pos2.x += var2 >> 4;
+ if (sprite->pos2.x > 0)
+ sprite->pos2.x = 0;
+ }
+ else
+ {
+ sprite->pos2.x -= var2 >> 4;
+ if (sprite->pos2.x < 0)
+ sprite->pos2.x = 0;
+ }
+
+ if (sprite->pos2.x == 0)
+ {
+ pan = SOUND_PAN_TARGET;
+ if (var1 != 0)
+ pan = SOUND_PAN_ATTACKER;
+
+ if (sprite->data[7] != 0)
+ PlaySE2WithPanning(SE_TB_KARA, pan);
+ else
+ PlaySE1WithPanning(SE_TB_KON, pan);
+
+ sprite->callback = SpriteCallbackDummy;
+ }
+}
+
+static void sub_8049630(struct Sprite *sprite)
+{
+ u8 var1;
+ u16 var2;
+
+ if (sprite->data[1] > 0)
+ {
+ sprite->data[1]--;
+ return;
+ }
+ var1 = sprite->data[2];
+ var2 = sprite->data[3];
+ var2 += 56;
+ sprite->data[3] = var2 & 0xFFF0;
+ if (var1 != 0)
+ sprite->pos2.x += var2 >> 4;
+ else
+ sprite->pos2.x -= var2 >> 4;
+ if (sprite->pos2.x + sprite->pos1.x > 248
+ || sprite->pos2.x + sprite->pos1.x < -8)
+ {
+ sprite->invisible = TRUE;
+ sprite->callback = SpriteCallbackDummy;
+ }
+}
+
+static void SpriteCB_StatusSummaryBallsOnSwitchout(struct Sprite *sprite)
+{
+ u8 barSpriteId = sprite->data[0];
+
+ sprite->pos2.x = gSprites[barSpriteId].pos2.x;
+ sprite->pos2.y = gSprites[barSpriteId].pos2.y;
+}
+
+static const u8 gUnknown_8260556[] = _("{HIGHLIGHT 02}");
+
+void UpdateNickInHealthbox(u8 healthboxSpriteId, struct Pokemon *mon)
+{
+ u8 nickname[POKEMON_NAME_LENGTH + 1];
+ u8 *ptr;
+ u32 windowId, spriteTileNum;
+ u8 *windowTileData;
+ u16 species;
+ u8 gender;
+
+ ptr = StringCopy(gDisplayedStringBattle, gUnknown_8260556);
+ GetMonData(mon, MON_DATA_NICKNAME, nickname);
+ StringGetEnd10(nickname);
+ ptr = StringCopy(ptr, nickname);
+ *ptr++ = EXT_CTRL_CODE_BEGIN;
+ *ptr++ = EXT_CTRL_CODE_COLOR;
+
+ gender = GetMonGender(mon);
+ species = GetMonData(mon, MON_DATA_SPECIES);
+
+ if ((species == SPECIES_NIDORAN_F || species == SPECIES_NIDORAN_M) && StringCompare(nickname, gSpeciesNames[species]) == 0)
+ gender = 100;
+
+ if (CheckBattleTypeGhost(mon, gSprites[healthboxSpriteId].hMain_Battler))
+ gender = 100;
+
+ // AddTextPrinterAndCreateWindowOnHealthbox's arguments are the same in all 3 cases.
+ // It's possible they may have been different in early development phases.
+ switch (gender)
+ {
+ default:
+ *ptr++ = TEXT_DYNAMIC_COLOR_2;
+ *ptr++ = EOS;
+ windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(gDisplayedStringBattle, 0, 3, &windowId);
+ break;
+ case MON_MALE:
+ *ptr++ = TEXT_DYNAMIC_COLOR_2;
+ *ptr++ = CHAR_MALE;
+ *ptr++ = EOS;
+ windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(gDisplayedStringBattle, 0, 3, &windowId);
+ break;
+ case MON_FEMALE:
+ *ptr++ = TEXT_DYNAMIC_COLOR_1;
+ *ptr++ = CHAR_FEMALE;
+ *ptr++ = EOS;
+ windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(gDisplayedStringBattle, 0, 3, &windowId);
+ break;
+ }
+
+ spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum * TILE_SIZE_4BPP;
+
+ if (GetBattlerSide(gSprites[healthboxSpriteId].data[6]) == B_SIDE_PLAYER)
+ {
+ TextIntoHealthboxObject((void*)(OBJ_VRAM0 + 0x40 + spriteTileNum), windowTileData, 6);
+ ptr = (void*)(OBJ_VRAM0);
+ if (!IsDoubleBattle())
+ ptr += spriteTileNum + 0x800;
+ else
+ ptr += spriteTileNum + 0x400;
+ TextIntoHealthboxObject(ptr, windowTileData + 0xC0, 1);
+ }
+ else
+ {
+ TextIntoHealthboxObject((void*)(OBJ_VRAM0 + 0x20 + spriteTileNum), windowTileData, 7);
+ }
+
+ RemoveWindowOnHealthbox(windowId);
+}
+void TryAddPokeballIconToHealthbox(u8 healthboxSpriteId, bool8 noStatus)
+{
+ u8 battlerId, healthBarSpriteId;
+
+ if (gBattleTypeFlags & (BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_OLD_MAN_TUTORIAL | BATTLE_TYPE_POKEDUDE))
+ return;
+
+ if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
+ return;
+
+ battlerId = gSprites[healthboxSpriteId].hMain_Battler;
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
+ return;
+ if (CheckBattleTypeGhost(&gEnemyParty[gBattlerPartyIndexes[battlerId]], battlerId))
+ return;
+ if (!GetSetPokedexFlag(SpeciesToNationalPokedexNum(GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES)), FLAG_GET_CAUGHT))
+ return;
+
+ healthBarSpriteId = gSprites[healthboxSpriteId].hMain_HealthBarSpriteId;
+
+ if (noStatus)
+ CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_70), (void*)(OBJ_VRAM0 + (gSprites[healthBarSpriteId].oam.tileNum + 8) * TILE_SIZE_4BPP), 32);
+ else
+ CpuFill32(0, (void*)(OBJ_VRAM0 + (gSprites[healthBarSpriteId].oam.tileNum + 8) * TILE_SIZE_4BPP), 32);
+}
+
+enum
+{
+ PAL_STATUS_PSN,
+ PAL_STATUS_PAR,
+ PAL_STATUS_SLP,
+ PAL_STATUS_FRZ,
+ PAL_STATUS_BRN
+};
+
+static const u16 sStatusIconColors[] = {
+ [PAL_STATUS_PSN] = RGB(24, 12, 24),
+ [PAL_STATUS_PAR] = RGB(23, 23, 3),
+ [PAL_STATUS_SLP] = RGB(20, 20, 17),
+ [PAL_STATUS_FRZ] = RGB(17, 22, 28),
+ [PAL_STATUS_BRN] = RGB(28, 14, 10)
+};
+
+static void UpdateStatusIconInHealthbox(u8 healthboxSpriteId)
+{
+ s32 i;
+ u8 battlerId, healthBarSpriteId;
+ u32 status, pltAdder;
+ const u8 *statusGfxPtr;
+ s16 tileNumAdder;
+ u8 statusPalId;
+
+ battlerId = gSprites[healthboxSpriteId].hMain_Battler;
+ healthBarSpriteId = gSprites[healthboxSpriteId].hMain_HealthBarSpriteId;
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
+ {
+ status = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_STATUS);
+ if (!IsDoubleBattle())
+ tileNumAdder = 0x1A;
+ else
+ tileNumAdder = 0x12;
+ }
+ else
+ {
+ status = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_STATUS);
+ tileNumAdder = 0x11;
+ }
+
+ if (status & STATUS1_SLEEP)
+ {
+ statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBattlerId(HEALTHBOX_GFX_STATUS_SLP_BATTLER0, battlerId));
+ statusPalId = PAL_STATUS_SLP;
+ }
+ else if (status & STATUS1_PSN_ANY)
+ {
+ statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBattlerId(HEALTHBOX_GFX_STATUS_PSN_BATTLER0, battlerId));
+ statusPalId = PAL_STATUS_PSN;
+ }
+ else if (status & STATUS1_BURN)
+ {
+ statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBattlerId(HEALTHBOX_GFX_STATUS_BRN_BATTLER0, battlerId));
+ statusPalId = PAL_STATUS_BRN;
+ }
+ else if (status & STATUS1_FREEZE)
+ {
+ statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBattlerId(HEALTHBOX_GFX_STATUS_FRZ_BATTLER0, battlerId));
+ statusPalId = PAL_STATUS_FRZ;
+ }
+ else if (status & STATUS1_PARALYSIS)
+ {
+ statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBattlerId(HEALTHBOX_GFX_STATUS_PRZ_BATTLER0, battlerId));
+ statusPalId = PAL_STATUS_PAR;
+ }
+ else
+ {
+ statusGfxPtr = GetHealthboxElementGfxPtr(HEALTHBOX_GFX_39);
+
+ for (i = 0; i < 3; i++)
+ CpuCopy32(statusGfxPtr, (void*)(OBJ_VRAM0 + (gSprites[healthboxSpriteId].oam.tileNum + tileNumAdder + i) * TILE_SIZE_4BPP), 32);
+
+ if (!gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars)
+ CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_1), (void *)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * TILE_SIZE_4BPP), 64);
+
+ TryAddPokeballIconToHealthbox(healthboxSpriteId, TRUE);
+ return;
+ }
+
+ pltAdder = gSprites[healthboxSpriteId].oam.paletteNum * 16;
+ pltAdder += battlerId + 12;
+
+ FillPalette(sStatusIconColors[statusPalId], pltAdder + 0x100, 2);
+ CpuCopy16(gPlttBufferUnfaded + 0x100 + pltAdder, (void*)(OBJ_PLTT + pltAdder * 2), 2);
+ CpuCopy32(statusGfxPtr, (void*)(OBJ_VRAM0 + (gSprites[healthboxSpriteId].oam.tileNum + tileNumAdder) * TILE_SIZE_4BPP), 96);
+ if (IsDoubleBattle() == TRUE || GetBattlerSide(battlerId) == B_SIDE_OPPONENT)
+ {
+ if (!gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars)
+ {
+ CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_0), (void*)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * TILE_SIZE_4BPP), 32);
+ CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_65), (void*)(OBJ_VRAM0 + (gSprites[healthBarSpriteId].oam.tileNum + 1) * TILE_SIZE_4BPP), 32);
+ }
+ }
+ TryAddPokeballIconToHealthbox(healthboxSpriteId, FALSE);
+}
+
+static u8 GetStatusIconForBattlerId(u8 statusElementId, u8 battlerId)
+{
+ u8 ret = statusElementId;
+
+ switch (statusElementId)
+ {
+ case HEALTHBOX_GFX_STATUS_PSN_BATTLER0:
+ if (battlerId == 0)
+ ret = HEALTHBOX_GFX_STATUS_PSN_BATTLER0;
+ else if (battlerId == 1)
+ ret = HEALTHBOX_GFX_STATUS_PSN_BATTLER1;
+ else if (battlerId == 2)
+ ret = HEALTHBOX_GFX_STATUS_PSN_BATTLER2;
+ else
+ ret = HEALTHBOX_GFX_STATUS_PSN_BATTLER3;
+ break;
+ case HEALTHBOX_GFX_STATUS_PRZ_BATTLER0:
+ if (battlerId == 0)
+ ret = HEALTHBOX_GFX_STATUS_PRZ_BATTLER0;
+ else if (battlerId == 1)
+ ret = HEALTHBOX_GFX_STATUS_PRZ_BATTLER1;
+ else if (battlerId == 2)
+ ret = HEALTHBOX_GFX_STATUS_PRZ_BATTLER2;
+ else
+ ret = HEALTHBOX_GFX_STATUS_PRZ_BATTLER3;
+ break;
+ case HEALTHBOX_GFX_STATUS_SLP_BATTLER0:
+ if (battlerId == 0)
+ ret = HEALTHBOX_GFX_STATUS_SLP_BATTLER0;
+ else if (battlerId == 1)
+ ret = HEALTHBOX_GFX_STATUS_SLP_BATTLER1;
+ else if (battlerId == 2)
+ ret = HEALTHBOX_GFX_STATUS_SLP_BATTLER2;
+ else
+ ret = HEALTHBOX_GFX_STATUS_SLP_BATTLER3;
+ break;
+ case HEALTHBOX_GFX_STATUS_FRZ_BATTLER0:
+ if (battlerId == 0)
+ ret = HEALTHBOX_GFX_STATUS_FRZ_BATTLER0;
+ else if (battlerId == 1)
+ ret = HEALTHBOX_GFX_STATUS_FRZ_BATTLER1;
+ else if (battlerId == 2)
+ ret = HEALTHBOX_GFX_STATUS_FRZ_BATTLER2;
+ else
+ ret = HEALTHBOX_GFX_STATUS_FRZ_BATTLER3;
+ break;
+ case HEALTHBOX_GFX_STATUS_BRN_BATTLER0:
+ if (battlerId == 0)
+ ret = HEALTHBOX_GFX_STATUS_BRN_BATTLER0;
+ else if (battlerId == 1)
+ ret = HEALTHBOX_GFX_STATUS_BRN_BATTLER1;
+ else if (battlerId == 2)
+ ret = HEALTHBOX_GFX_STATUS_BRN_BATTLER2;
+ else
+ ret = HEALTHBOX_GFX_STATUS_BRN_BATTLER3;
+ break;
+ }
+ return ret;
+}
+
+static void UpdateSafariBallsTextOnHealthbox(u8 healthboxSpriteId)
+{
+ u32 windowId, spriteTileNum;
+ u8 *windowTileData;
+
+ windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(gText_SafariBalls, 0, 3, &windowId);
+ spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum * TILE_SIZE_4BPP;
+ TextIntoHealthboxObject((void*)(OBJ_VRAM0 + 0x40) + spriteTileNum, windowTileData, 6);
+ TextIntoHealthboxObject((void*)(OBJ_VRAM0 + 0x800) + spriteTileNum, windowTileData + 0xC0, 2);
+ RemoveWindowOnHealthbox(windowId);
+}
+
+static void UpdateLeftNoOfBallsTextOnHealthbox(u8 healthboxSpriteId)
+{
+ u8 text[16];
+ u8 *txtPtr;
+ u32 windowId, spriteTileNum;
+ u8 *windowTileData;
+
+ txtPtr = StringCopy(text, gText_HighlightRed_Left);
+ ConvertIntToDecimalStringN(txtPtr, gNumSafariBalls, STR_CONV_MODE_LEFT_ALIGN, 2);
+
+ windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, GetStringRightAlignXOffset(0, text, 0x2F), 3, &windowId);
+ spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum * TILE_SIZE_4BPP;
+ SafariTextIntoHealthboxObject((void*)(OBJ_VRAM0 + 0x2C0) + spriteTileNum, windowTileData, 2);
+ SafariTextIntoHealthboxObject((void*)(OBJ_VRAM0 + 0xA00) + spriteTileNum, windowTileData + 0x40, 4);
+ RemoveWindowOnHealthbox(windowId);
+}
+
+void UpdateHealthboxAttribute(u8 healthboxSpriteId, struct Pokemon *mon, u8 elementId)
+{
+ s32 maxHp, currHp;
+ u8 battlerId = gSprites[healthboxSpriteId].hMain_Battler;
+
+ if (elementId == HEALTHBOX_ALL && !IsDoubleBattle())
+ GetBattlerSide(battlerId); // Pointless function call.
+
+ if (GetBattlerSide(gSprites[healthboxSpriteId].hMain_Battler) == B_SIDE_PLAYER)
+ {
+ u8 isDoubles;
+
+ if (elementId == HEALTHBOX_LEVEL || elementId == HEALTHBOX_ALL)
+ UpdateLvlInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_LEVEL));
+ if (elementId == HEALTHBOX_CURRENT_HP || elementId == HEALTHBOX_ALL)
+ UpdateHpTextInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_HP), HP_CURRENT);
+ if (elementId == HEALTHBOX_MAX_HP || elementId == HEALTHBOX_ALL)
+ UpdateHpTextInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_MAX_HP), HP_MAX);
+ if (elementId == HEALTHBOX_HEALTH_BAR || elementId == HEALTHBOX_ALL)
+ {
+ LoadBattleBarGfx(0);
+ maxHp = GetMonData(mon, MON_DATA_MAX_HP);
+ currHp = GetMonData(mon, MON_DATA_HP);
+ SetBattleBarStruct(battlerId, healthboxSpriteId, maxHp, currHp, 0);
+ MoveBattleBar(battlerId, healthboxSpriteId, HEALTH_BAR, 0);
+ }
+ isDoubles = IsDoubleBattle();
+ if (!isDoubles && (elementId == HEALTHBOX_EXP_BAR || elementId == HEALTHBOX_ALL))
+ {
+ u16 species;
+ u32 exp, currLevelExp;
+ s32 currExpBarValue, maxExpBarValue;
+ u8 level;
+
+ LoadBattleBarGfx(3);
+ species = GetMonData(mon, MON_DATA_SPECIES);
+ level = GetMonData(mon, MON_DATA_LEVEL);
+ exp = GetMonData(mon, MON_DATA_EXP);
+ currLevelExp = gExperienceTables[gBaseStats[species].growthRate][level];
+ currExpBarValue = exp - currLevelExp;
+ maxExpBarValue = gExperienceTables[gBaseStats[species].growthRate][level + 1] - currLevelExp;
+ SetBattleBarStruct(battlerId, healthboxSpriteId, maxExpBarValue, currExpBarValue, isDoubles);
+ MoveBattleBar(battlerId, healthboxSpriteId, EXP_BAR, 0);
+ }
+ if (elementId == HEALTHBOX_NICK || elementId == HEALTHBOX_ALL)
+ UpdateNickInHealthbox(healthboxSpriteId, mon);
+ if (elementId == HEALTHBOX_STATUS_ICON || elementId == HEALTHBOX_ALL)
+ UpdateStatusIconInHealthbox(healthboxSpriteId);
+ if (elementId == HEALTHBOX_SAFARI_ALL_TEXT)
+ UpdateSafariBallsTextOnHealthbox(healthboxSpriteId);
+ if (elementId == HEALTHBOX_SAFARI_ALL_TEXT || elementId == HEALTHBOX_SAFARI_BALLS_TEXT)
+ UpdateLeftNoOfBallsTextOnHealthbox(healthboxSpriteId);
+ }
+ else
+ {
+ if (elementId == HEALTHBOX_LEVEL || elementId == HEALTHBOX_ALL)
+ UpdateLvlInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_LEVEL));
+ if (elementId == HEALTHBOX_HEALTH_BAR || elementId == HEALTHBOX_ALL)
+ {
+ LoadBattleBarGfx(0);
+ maxHp = GetMonData(mon, MON_DATA_MAX_HP);
+ currHp = GetMonData(mon, MON_DATA_HP);
+ SetBattleBarStruct(battlerId, healthboxSpriteId, maxHp, currHp, 0);
+ MoveBattleBar(battlerId, healthboxSpriteId, HEALTH_BAR, 0);
+ }
+ if (elementId == HEALTHBOX_NICK || elementId == HEALTHBOX_ALL)
+ UpdateNickInHealthbox(healthboxSpriteId, mon);
+ if (elementId == HEALTHBOX_STATUS_ICON || elementId == HEALTHBOX_ALL)
+ UpdateStatusIconInHealthbox(healthboxSpriteId);
+ }
+}
+
+#define B_EXPBAR_PIXELS 64
+#define B_HEALTHBAR_PIXELS 48
+
+s32 MoveBattleBar(u8 battlerId, u8 healthboxSpriteId, u8 whichBar, u8 unused)
+{
+ s32 currentBarValue;
+
+ if (whichBar == HEALTH_BAR) // health bar
+ {
+ currentBarValue = CalcNewBarValue(gBattleSpritesDataPtr->battleBars[battlerId].maxValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].oldValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].receivedValue,
+ &gBattleSpritesDataPtr->battleBars[battlerId].currValue,
+ B_HEALTHBAR_PIXELS / 8, 1);
+ }
+ else // exp bar
+ {
+ u16 expFraction = GetScaledExpFraction(gBattleSpritesDataPtr->battleBars[battlerId].oldValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].receivedValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].maxValue, 8);
+ if (expFraction == 0)
+ expFraction = 1;
+ expFraction = abs(gBattleSpritesDataPtr->battleBars[battlerId].receivedValue / expFraction);
+
+ currentBarValue = CalcNewBarValue(gBattleSpritesDataPtr->battleBars[battlerId].maxValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].oldValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].receivedValue,
+ &gBattleSpritesDataPtr->battleBars[battlerId].currValue,
+ B_EXPBAR_PIXELS / 8, expFraction);
+ }
+
+ if (whichBar == EXP_BAR || (whichBar == HEALTH_BAR && !gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars))
+ MoveBattleBarGraphically(battlerId, whichBar);
+
+ if (currentBarValue == -1)
+ gBattleSpritesDataPtr->battleBars[battlerId].currValue = 0;
+
+ return currentBarValue;
+}
+
+static void MoveBattleBarGraphically(u8 battlerId, u8 whichBar)
+{
+ u8 array[8];
+ u8 filledPixelsCount, level;
+ u8 barElementId;
+ u8 i;
+
+ switch (whichBar)
+ {
+ case HEALTH_BAR:
+ filledPixelsCount = CalcBarFilledPixels(gBattleSpritesDataPtr->battleBars[battlerId].maxValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].oldValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].receivedValue,
+ &gBattleSpritesDataPtr->battleBars[battlerId].currValue,
+ array, B_HEALTHBAR_PIXELS / 8);
+
+ if (filledPixelsCount > (B_HEALTHBAR_PIXELS * 50 / 100)) // more than 50 % hp
+ barElementId = HEALTHBOX_GFX_HP_BAR_GREEN;
+ else if (filledPixelsCount > (B_HEALTHBAR_PIXELS * 20 / 100)) // more than 20% hp
+ barElementId = HEALTHBOX_GFX_HP_BAR_YELLOW;
+ else
+ barElementId = HEALTHBOX_GFX_HP_BAR_RED; // 20 % or less
+
+ for (i = 0; i < 6; i++)
+ {
+ u8 healthbarSpriteId = gSprites[gBattleSpritesDataPtr->battleBars[battlerId].healthboxSpriteId].hMain_HealthBarSpriteId;
+ if (i < 2)
+ CpuCopy32(GetHealthboxElementGfxPtr(barElementId) + array[i] * 32,
+ (void*)(OBJ_VRAM0 + (gSprites[healthbarSpriteId].oam.tileNum + 2 + i) * TILE_SIZE_4BPP), 32);
+ else
+ CpuCopy32(GetHealthboxElementGfxPtr(barElementId) + array[i] * 32,
+ (void*)(OBJ_VRAM0 + 64 + (i + gSprites[healthbarSpriteId].oam.tileNum) * TILE_SIZE_4BPP), 32);
+ }
+ break;
+ case EXP_BAR:
+ CalcBarFilledPixels(gBattleSpritesDataPtr->battleBars[battlerId].maxValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].oldValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].receivedValue,
+ &gBattleSpritesDataPtr->battleBars[battlerId].currValue,
+ array, B_EXPBAR_PIXELS / 8);
+ level = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_LEVEL);
+ if (level == MAX_LEVEL)
+ {
+ for (i = 0; i < 8; i++)
+ array[i] = 0;
+ }
+ for (i = 0; i < 8; i++)
+ {
+ if (i < 4)
+ CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_12) + array[i] * 32,
+ (void*)(OBJ_VRAM0 + (gSprites[gBattleSpritesDataPtr->battleBars[battlerId].healthboxSpriteId].oam.tileNum + 0x24 + i) * TILE_SIZE_4BPP), 32);
+ else
+ CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_12) + array[i] * 32,
+ (void*)(OBJ_VRAM0 + 0xB80 + (i + gSprites[gBattleSpritesDataPtr->battleBars[battlerId].healthboxSpriteId].oam.tileNum) * TILE_SIZE_4BPP), 32);
+ }
+ break;
+ }
+}
+static s32 CalcNewBarValue(s32 maxValue, s32 oldValue, s32 receivedValue, s32 *currValue, u8 scale, u16 toAdd)
+{
+ s32 ret, newValue;
+ scale *= 8;
+
+ if (*currValue == -32768) // first function call
+ {
+ if (maxValue < scale)
+ *currValue = Q_24_8(oldValue);
+ else
+ *currValue = oldValue;
+ }
+
+ newValue = oldValue - receivedValue;
+ if (newValue < 0)
+ newValue = 0;
+ else if (newValue > maxValue)
+ newValue = maxValue;
+
+ if (maxValue < scale)
+ {
+ if (newValue == Q_24_8_TO_INT(*currValue) && (*currValue & 0xFF) == 0)
+ return -1;
+ }
+ else
+ {
+ if (newValue == *currValue) // we're done, the bar's value has been updated
+ return -1;
+ }
+
+ if (maxValue < scale) // handle cases of max var having less pixels than the whole bar
+ {
+ s32 toAdd_ = Q_24_8(maxValue) / scale;
+
+ if (receivedValue < 0) // fill bar right
+ {
+ *currValue += toAdd_;
+ ret = Q_24_8_TO_INT(*currValue);
+ if (ret >= newValue)
+ {
+ *currValue = Q_24_8(newValue);
+ ret = newValue;
+ }
+ }
+ else // move bar left
+ {
+ *currValue -= toAdd_;
+ ret = Q_24_8_TO_INT(*currValue);
+ // try round up
+ if ((*currValue & 0xFF) > 0)
+ ret++;
+ if (ret <= newValue)
+ {
+ *currValue = Q_24_8(newValue);
+ ret = newValue;
+ }
+ }
+ }
+ else
+ {
+ if (receivedValue < 0) // fill bar right
+ {
+ *currValue += toAdd;
+ if (*currValue > newValue)
+ *currValue = newValue;
+ ret = *currValue;
+ }
+ else // move bar left
+ {
+ *currValue -= toAdd;
+ if (*currValue < newValue)
+ *currValue = newValue;
+ ret = *currValue;
+ }
+ }
+
+ return ret;
+}
+
+static u8 CalcBarFilledPixels(s32 maxValue, s32 oldValue, s32 receivedValue, s32 *currValue, u8 *arg4, u8 scale)
+{
+ u8 pixels, filledPixels, totalPixels;
+ u8 i;
+
+ s32 newValue = oldValue - receivedValue;
+ if (newValue < 0)
+ newValue = 0;
+ else if (newValue > maxValue)
+ newValue = maxValue;
+
+ totalPixels = scale * 8;
+
+ for (i = 0; i < scale; i++)
+ arg4[i] = 0;
+
+ if (maxValue < totalPixels)
+ pixels = (*currValue * totalPixels / maxValue) >> 8;
+ else
+ pixels = *currValue * totalPixels / maxValue;
+
+ filledPixels = pixels;
+
+ if (filledPixels == 0 && newValue > 0)
+ {
+ arg4[0] = 1;
+ filledPixels = 1;
+ }
+ else
+ {
+ for (i = 0; i < scale; i++)
+ {
+ if (pixels >= 8)
+ {
+ arg4[i] = 8;
+ }
+ else
+ {
+ arg4[i] = pixels;
+ break;
+ }
+ pixels -= 8;
+ }
+ }
+
+ return filledPixels;
+}
+
+// These functions seem as if they were made for testing the health bar.
+static s16 sub_804A460(struct TestingBar *barInfo, s32 *currValue, u8 bg, u8 x, u8 y)
+{
+ s16 ret;
+
+ ret = CalcNewBarValue(barInfo->maxValue,
+ barInfo->oldValue,
+ barInfo->receivedValue,
+ currValue, B_HEALTHBAR_PIXELS / 8, 1);
+
+ sub_804A510(barInfo, currValue, bg, x, y);
+
+ return ret;
+}
+
+static s16 sub_804A4C8(struct TestingBar *barInfo, s32 *currValue)
+{
+ s16 ret;
+
+ ret = CalcNewBarValue(barInfo->maxValue,
+ barInfo->oldValue,
+ barInfo->receivedValue,
+ currValue, B_HEALTHBAR_PIXELS / 8, 1);
+
+ return ret;
+}
+
+static void sub_804A4F0(struct TestingBar *barInfo, s32 *currValue, u8 bg, u8 x, u8 y)
+{
+ sub_804A510(barInfo, currValue, bg, x, y);
+}
+
+static void sub_804A510(struct TestingBar *barInfo, s32 *currValue, u8 bg, u8 x, u8 y)
+{
+ u8 spC[B_HEALTHBAR_PIXELS / 8];
+ u16 tiles[B_HEALTHBAR_PIXELS / 8];
+ u8 i;
+
+ CalcBarFilledPixels(barInfo->maxValue,
+ barInfo->oldValue,
+ barInfo->receivedValue,
+ currValue, spC, B_HEALTHBAR_PIXELS / 8);
+
+ for (i = 0; i < B_HEALTHBAR_PIXELS / 8; i++)
+ {
+ tiles[i] = (barInfo->pal << 12) | (barInfo->tileOffset + spC[i]);
+ }
+
+ CopyToBgTilemapBufferRect_ChangePalette(bg, tiles, x, y, 6, 1, 17);
+}
+
+static u8 GetScaledExpFraction(s32 oldValue, s32 receivedValue, s32 maxValue, u8 scale)
+{
+ s32 newVal, result;
+ s8 oldToMax, newToMax;
+
+ scale *= 8;
+ newVal = oldValue - receivedValue;
+
+ if (newVal < 0)
+ newVal = 0;
+ else if (newVal > maxValue)
+ newVal = maxValue;
+
+ oldToMax = oldValue * scale / maxValue;
+ newToMax = newVal * scale / maxValue;
+ result = oldToMax - newToMax;
+
+ return abs(result);
+}
+
+u8 GetScaledHPFraction(s16 hp, s16 maxhp, u8 scale)
+{
+ u8 result = hp * scale / maxhp;
+
+ if (result == 0 && hp > 0)
+ return 1;
+
+ return result;
+}
+
+u8 GetHPBarLevel(s16 hp, s16 maxhp)
+{
+ u8 result;
+
+ if (hp == maxhp)
+ {
+ result = HP_BAR_FULL;
+ }
+ else
+ {
+ u8 fraction = GetScaledHPFraction(hp, maxhp, B_HEALTHBAR_PIXELS);
+ if (fraction > (B_HEALTHBAR_PIXELS * 50 / 100)) // more than 50 % hp
+ result = HP_BAR_GREEN;
+ else if (fraction > (B_HEALTHBAR_PIXELS * 20 / 100)) // more than 20% hp
+ result = HP_BAR_YELLOW;
+ else if (fraction > 0)
+ result = HP_BAR_RED;
+ else
+ result = HP_BAR_EMPTY;
+ }
+
+ return result;
+}
+
+static const struct WindowTemplate sHealthboxWindowTemplate = {
+ .bg = 0,
+ .tilemapLeft = 0,
+ .tilemapTop = 0,
+ .width = 8,
+ .height = 2,
+ .paletteNum = 0,
+ .baseBlock = 0x000
+};
+
+
+static u8* AddTextPrinterAndCreateWindowOnHealthbox(const u8 *str, u32 x, u32 y, u32 *windowId)
+{
+ u16 winId;
+ u8 color[3];
+ struct WindowTemplate winTemplate = sHealthboxWindowTemplate;
+
+ winId = AddWindow(&winTemplate);
+ FillWindowPixelBuffer(winId, PIXEL_FILL(2));
+
+ color[0] = 2;
+ color[1] = 1;
+ color[2] = 3;
+
+ AddTextPrinterParameterized4(winId, 0, x, y, 0, 0, color, -1, str);
+
+ *windowId = winId;
+ return (u8*)(GetWindowAttribute(winId, WINDOW_TILE_DATA));
+}
+
+static void RemoveWindowOnHealthbox(u32 windowId)
+{
+ RemoveWindow(windowId);
+}
+
+static void TextIntoHealthboxObject(void *dest, u8 *windowTileData, s32 windowWidth)
+{
+ CpuCopy32(windowTileData + 256, dest + 256, windowWidth * TILE_SIZE_4BPP);
+// + 256 as that prevents the top 4 blank rows of sHealthboxWindowTemplate from being copied
+ if (windowWidth > 0)
+ {
+ do
+ {
+ CpuCopy32(windowTileData + 20, dest + 20, 12);
+ dest += 32, windowTileData += 32;
+ windowWidth--;
+ } while (windowWidth != 0);
+ }
+}
+
+static void SafariTextIntoHealthboxObject(void *dest, u8 *windowTileData, u32 windowWidth)
+{
+ CpuCopy32(windowTileData, dest, windowWidth * TILE_SIZE_4BPP);
+ CpuCopy32(windowTileData + 256, dest + 256, windowWidth * TILE_SIZE_4BPP);
+}
diff --git a/src/battle_message.c b/src/battle_message.c
index 396c4c7f0..2513aaff6 100644
--- a/src/battle_message.c
+++ b/src/battle_message.c
@@ -1254,7 +1254,7 @@ const u8 *const gUnknown_83FE7F4[] = {
sText_Speed
};
-const u8 gUnknown_83FE80C[] = _("{HIGHLIGHT 2}SAFARI BALLS"); //
+const u8 gText_SafariBalls[] = _("{HIGHLIGHT 2}SAFARI BALLS"); //
const u8 gText_HighlightRed_Left[] = _("{HIGHLIGHT 2}Left: ");
const u8 gText_HighlightRed[] = _("{HIGHLIGHT 2}");
const u8 gText_Sleep[] = _("sleep");
diff --git a/src/battle_setup.c b/src/battle_setup.c
index dee0c492b..056fe9273 100644
--- a/src/battle_setup.c
+++ b/src/battle_setup.c
@@ -9,7 +9,7 @@
#include "safari_zone.h"
#include "quest_log.h"
#include "script.h"
-#include "script_pokemon_util_80A0058.h"
+#include "script_pokemon_util.h"
#include "strings.h"
#include "string_util.h"
#include "event_data.h"
diff --git a/src/battle_tower.c b/src/battle_tower.c
index 86ed75273..cecc05e29 100644
--- a/src/battle_tower.c
+++ b/src/battle_tower.c
@@ -18,7 +18,7 @@
#include "new_game.h"
#include "save.h"
#include "item.h"
-#include "script_pokemon_util_80A0058.h"
+#include "script_pokemon_util.h"
#include "constants/species.h"
#include "constants/items.h"
#include "constants/moves.h"
diff --git a/src/data/text/map_section_names.h b/src/data/text/map_section_names.h
new file mode 100644
index 000000000..5a18fa7c9
--- /dev/null
+++ b/src/data/text/map_section_names.h
@@ -0,0 +1,109 @@
+const u8 gMapSecName_PalletTown[] = _("PALLET TOWN");
+const u8 gMapSecName_ViridianCity[] = _("VIRIDIAN CITY");
+const u8 gMapSecName_PewterCity[] = _("PEWTER CITY");
+const u8 gMapSecName_CeruleanCity[] = _("CERULEAN CITY");
+const u8 gMapSecName_LavenderTown[] = _("LAVENDER TOWN");
+const u8 gMapSecName_VermilionCity[] = _("VERMILION CITY");
+const u8 gMapSecName_CeladonCity[] = _("CELADON CITY");
+const u8 gMapSecName_FuchsiaCity[] = _("FUCHSIA CITY");
+const u8 gMapSecName_CinnabarIsland[] = _("CINNABAR ISLAND");
+const u8 gMapSecName_IndigoPlateau[] = _("INDIGO PLATEAU");
+const u8 gMapSecName_SaffronCity[] = _("SAFFRON CITY");
+const u8 gMapSecName_Route4[] = _("ROUTE 4");
+const u8 gMapSecName_Route10[] = _("ROUTE 10");
+const u8 gMapSecName_Route1[] = _("ROUTE 1");
+const u8 gMapSecName_Route2[] = _("ROUTE 2");
+const u8 gMapSecName_Route3[] = _("ROUTE 3");
+const u8 gMapSecName_Route4_2[] = _("ROUTE 4");
+const u8 gMapSecName_Route5[] = _("ROUTE 5");
+const u8 gMapSecName_Route6[] = _("ROUTE 6");
+const u8 gMapSecName_Route7[] = _("ROUTE 7");
+const u8 gMapSecName_Route8[] = _("ROUTE 8");
+const u8 gMapSecName_Route9[] = _("ROUTE 9");
+const u8 gMapSecName_Route10_2[] = _("ROUTE 10");
+const u8 gMapSecName_Route11[] = _("ROUTE 11");
+const u8 gMapSecName_Route12[] = _("ROUTE 12");
+const u8 gMapSecName_Route13[] = _("ROUTE 13");
+const u8 gMapSecName_Route14[] = _("ROUTE 14");
+const u8 gMapSecName_Route15[] = _("ROUTE 15");
+const u8 gMapSecName_Route16[] = _("ROUTE 16");
+const u8 gMapSecName_Route17[] = _("ROUTE 17");
+const u8 gMapSecName_Route18[] = _("ROUTE 18");
+const u8 gMapSecName_Route19[] = _("ROUTE 19");
+const u8 gMapSecName_Route20[] = _("ROUTE 20");
+const u8 gMapSecName_Route21[] = _("ROUTE 21");
+const u8 gMapSecName_Route22[] = _("ROUTE 22");
+const u8 gMapSecName_Route23[] = _("ROUTE 23");
+const u8 gMapSecName_Route24[] = _("ROUTE 24");
+const u8 gMapSecName_Route25[] = _("ROUTE 25");
+const u8 gMapSecName_ViridianForest[] = _("VIRIDIAN FOREST");
+const u8 gMapSecName_MtMoon[] = _("MT. MOON");
+const u8 gMapSecName_SSAnne[] = _("S.S. ANNE");
+const u8 gMapSecName_UndergroundPath[] = _("UNDERGROUND PATH");
+const u8 gMapSecName_UndergroundPath_2[] = _("UNDERGROUND PATH");
+const u8 gMapSecName_DiglettsCave[] = _("DIGLETT'S CAVE");
+const u8 gMapSecName_VictoryRoad[] = _("VICTORY ROAD");
+const u8 gMapSecName_RocketHideout[] = _("ROCKET HIDEOUT");
+const u8 gMapSecName_SilphCo[] = _("SILPH CO.");
+const u8 gMapSecName_PokemonMansion[] = _("POKéMON MANSION");
+const u8 gMapSecName_SafariZone[] = _("SAFARI ZONE");
+const u8 gMapSecName_PokemonLeague[] = _("POKéMON LEAGUE");
+const u8 gMapSecName_RockTunnel[] = _("ROCK TUNNEL");
+const u8 gMapSecName_SeafoamIslands[] = _("SEAFOAM ISLANDS");
+const u8 gMapSecName_PokemonTower[] = _("POKéMON TOWER");
+const u8 gMapSecName_CeruleanCave[] = _("CERULEAN CAVE");
+const u8 gMapSecName_PowerPlant[] = _("POWER PLANT");
+const u8 gMapSecName_OneIsland[] = _("ONE ISLAND");
+const u8 gMapSecName_TwoIsland[] = _("TWO ISLAND");
+const u8 gMapSecName_ThreeIsland[] = _("THREE ISLAND");
+const u8 gMapSecName_FourIsland[] = _("FOUR ISLAND");
+const u8 gMapSecName_FiveIsland[] = _("FIVE ISLAND");
+const u8 gMapSecName_SevenIsland[] = _("SEVEN ISLAND");
+const u8 gMapSecName_SixIsland[] = _("SIX ISLAND");
+const u8 gMapSecName_KindleRoad[] = _("KINDLE ROAD");
+const u8 gMapSecName_TreasureBeach[] = _("TREASURE BEACH");
+const u8 gMapSecName_CapeBrink[] = _("CAPE BRINK");
+const u8 gMapSecName_BondBridge[] = _("BOND BRIDGE");
+const u8 gMapSecName_ThreeIslePort[] = _("THREE ISLE PORT");
+const u8 gMapSecName_SeviiIsle6[] = _("SEVII ISLE 6");
+const u8 gMapSecName_SeviiIsle7[] = _("SEVII ISLE 7");
+const u8 gMapSecName_SeviiIsle8[] = _("SEVII ISLE 8");
+const u8 gMapSecName_SeviiIsle9[] = _("SEVII ISLE 9");
+const u8 gMapSecName_ResortGorgeous[] = _("RESORT GORGEOUS");
+const u8 gMapSecName_WaterLabyrinth[] = _("WATER LABYRINTH");
+const u8 gMapSecName_FiveIsleMeadow[] = _("FIVE ISLE MEADOW");
+const u8 gMapSecName_MemorialPillar[] = _("MEMORIAL PILLAR");
+const u8 gMapSecName_OutcastIsland[] = _("OUTCAST ISLAND");
+const u8 gMapSecName_GreenPath[] = _("GREEN PATH");
+const u8 gMapSecName_WaterPath[] = _("WATER PATH");
+const u8 gMapSecName_RuinValley[] = _("RUIN VALLEY");
+const u8 gMapSecName_TrainerTower[] = _("TRAINER TOWER");
+const u8 gMapSecName_CanyonEntrance[] = _("CANYON ENTRANCE");
+const u8 gMapSecName_SevaultCanyon[] = _("SEVAULT CANYON");
+const u8 gMapSecName_TanobyRuins[] = _("TANOBY RUINS");
+const u8 gMapSecName_SeviiIsle22[] = _("SEVII ISLE 22");
+const u8 gMapSecName_SeviiIsle23[] = _("SEVII ISLE 23");
+const u8 gMapSecName_SeviiIsle24[] = _("SEVII ISLE 24");
+const u8 gMapSecName_NavelRock[] = _("NAVEL ROCK");
+const u8 gMapSecName_MtEmber[] = _("MT. EMBER");
+const u8 gMapSecName_BerryForest[] = _("BERRY FOREST");
+const u8 gMapSecName_IcefallCave[] = _("ICEFALL CAVE");
+const u8 gMapSecName_RocketWarehouse[] = _("ROCKET WAREHOUSE");
+const u8 gMapSecName_TrainerTower_2[] = _("TRAINER TOWER");
+const u8 gMapSecName_DottedHole[] = _("DOTTED HOLE");
+const u8 gMapSecName_LostCave[] = _("LOST CAVE");
+const u8 gMapSecName_PatternBush[] = _("PATTERN BUSH");
+const u8 gMapSecName_AlteringCave[] = _("ALTERING CAVE");
+const u8 gMapSecName_TanobyChambers[] = _("TANOBY CHAMBERS");
+const u8 gMapSecName_ThreeIslePath[] = _("THREE ISLE PATH");
+const u8 gMapSecName_TanobyKey[] = _("TANOBY KEY");
+const u8 gMapSecName_BirthIsland[] = _("BIRTH ISLAND");
+const u8 gMapSecName_MoneanChamber[] = _("MONEAN CHAMBER");
+const u8 gMapSecName_LiptooChamber[] = _("LIPTOO CHAMBER");
+const u8 gMapSecName_WeepthChamber[] = _("WEEPTH CHAMBER");
+const u8 gMapSecName_DilfordChamber[] = _("DILFORD CHAMBER");
+const u8 gMapSecName_ScufibChamber[] = _("SCUFIB CHAMBER");
+const u8 gMapSecName_RixyChamber[] = _("RIXY CHAMBER");
+const u8 gMapSecName_ViapoisChamber[] = _("VIAPOIS CHAMBER");
+const u8 gMapSecName_EmberSpa[] = _("EMBER SPA");
+const u8 gMapSecName_CeladonDept[] = _("CELADON DEPT.");
diff --git a/src/image_processing_effects.c b/src/image_processing_effects.c
new file mode 100644
index 000000000..fdd62f7a5
--- /dev/null
+++ b/src/image_processing_effects.c
@@ -0,0 +1,4425 @@
+#include "global.h"
+#include "image_processing_effects.h"
+
+// IWRAM common
+u8 gCanvasColumnStart;
+u16 (*gCanvasPixels)[][32];
+u8 gCanvasRowEnd;
+u8 gCanvasHeight;
+u8 gCanvasColumnEnd;
+u8 gCanvasRowStart;
+u8 gCanvasMonPersonality;
+u8 gCanvasWidth;
+u16 *gCanvasPalette;
+u16 gCanvasPaletteStart;
+
+static void ApplyImageEffect_Pointillism(void);
+static void ApplyImageEffect_Blur(void);
+static void ApplyImageEffect_BlackOutline(void);
+static void ApplyImageEffect_Invert(void);
+static void ApplyImageEffect_BlackAndWhite(void);
+static void ApplyImageEffect_BlurRight(void);
+static void ApplyImageEffect_BlurDown(void);
+static void ApplyImageEffect_Shimmer(void);
+static void ApplyImageEffect_Grayscale(void);
+static void ApplyImageEffect_PersonalityColor(u8);
+static void ApplyImageEffect_RedChannelGrayscale(u8);
+static void ApplyImageEffect_RedChannelGrayscaleHighlight(u8);
+static void AddPointillismPoints(u16);
+static u16 ConvertColorToGrayscale(u16*);
+static u16 QuantizePixel_Blur(u16*, u16*, u16*);
+static u16 QuantizePixel_PersonalityColor(u16*, u8);
+static u16 QuantizePixel_BlackAndWhite(u16*);
+static u16 QuantizePixel_BlackOutline(u16*, u16*);
+static u16 QuantizePixel_Invert(u16*);
+static u16 QuantizePixel_BlurHard(u16*, u16*, u16*);
+static u16 QuantizePixel_MotionBlur(u16*, u16*);
+static u16 GetColorFromPersonality(u8);
+static void QuantizePalette_Standard(bool8);
+static void SetPresetPalette_PrimaryColors(void);
+static void QuantizePalette_PrimaryColors(void);
+static void SetPresetPalette_Grayscale(void);
+static void QuantizePalette_Grayscale(void);
+static void SetPresetPalette_GrayscaleSmall(void);
+static void QuantizePalette_GrayscaleSmall(void);
+static void SetPresetPalette_BlackAndWhite(void);
+static void QuantizePalette_BlackAndWhite(void);
+static u16 QuantizePixel_Standard(u16*);
+static u16 QuantizePixel_GrayscaleSmall(u16*);
+static u16 QuantizePixel_Grayscale(u16*);
+static u16 QuantizePixel_PrimaryColors(u16*);
+
+static const u8 sPointillismPoints[][3] = {
+ {0x00, 0x1d, 0x1c},
+ {0x0e, 0x1e, 0x1b},
+ {0x00, 0x01, 0x32},
+ {0x2e, 0x1e, 0x37},
+ {0x0a, 0x22, 0x1f},
+ {0x05, 0x26, 0x2e},
+ {0x12, 0x17, 0x1e},
+ {0x1a, 0x03, 0x11},
+ {0x05, 0x11, 0x18},
+ {0x05, 0x27, 0x2f},
+ {0x1a, 0x3f, 0x12},
+ {0x22, 0x3f, 0x16},
+ {0x2b, 0x2f, 0x2e},
+ {0x11, 0x02, 0x2d},
+ {0x23, 0x0d, 0x28},
+ {0x17, 0x0c, 0x19},
+ {0x2f, 0x0e, 0x13},
+ {0x30, 0x18, 0x20},
+ {0x2d, 0x28, 0x22},
+ {0x01, 0x03, 0x19},
+ {0x0e, 0x2a, 0x2b},
+ {0x22, 0x15, 0x25},
+ {0x22, 0x0a, 0x26},
+ {0x39, 0x06, 0x23},
+ {0x16, 0x07, 0x2f},
+ {0x22, 0x3a, 0x1b},
+ {0x3b, 0x36, 0x35},
+ {0x0a, 0x2b, 0x24},
+ {0x36, 0x09, 0x12},
+ {0x1c, 0x2f, 0x23},
+ {0x2e, 0x38, 0x2c},
+ {0x05, 0x2a, 0x20},
+ {0x07, 0x14, 0x32},
+ {0x31, 0x08, 0x17},
+ {0x1a, 0x24, 0x2d},
+ {0x22, 0x0a, 0x16},
+ {0x1b, 0x26, 0x2b},
+ {0x29, 0x16, 0x11},
+ {0x35, 0x08, 0x14},
+ {0x1e, 0x08, 0x14},
+ {0x05, 0x31, 0x14},
+ {0x38, 0x31, 0x17},
+ {0x34, 0x33, 0x12},
+ {0x11, 0x09, 0x1f},
+ {0x28, 0x3d, 0x32},
+ {0x35, 0x03, 0x1e},
+ {0x3c, 0x2b, 0x2e},
+ {0x10, 0x01, 0x17},
+ {0x03, 0x3e, 0x22},
+ {0x17, 0x18, 0x34},
+ {0x08, 0x29, 0x19},
+ {0x03, 0x24, 0x28},
+ {0x3d, 0x33, 0x2f},
+ {0x31, 0x24, 0x19},
+ {0x1b, 0x18, 0x26},
+ {0x07, 0x0d, 0x25},
+ {0x2d, 0x3f, 0x12},
+ {0x2f, 0x15, 0x25},
+ {0x29, 0x0f, 0x12},
+ {0x07, 0x2c, 0x12},
+ {0x2c, 0x0b, 0x26},
+ {0x12, 0x1a, 0x16},
+ {0x00, 0x0b, 0x2f},
+ {0x16, 0x35, 0x24},
+ {0x1f, 0x1c, 0x22},
+ {0x29, 0x33, 0x27},
+ {0x3b, 0x30, 0x17},
+ {0x11, 0x06, 0x35},
+ {0x3e, 0x31, 0x2f},
+ {0x11, 0x3a, 0x25},
+ {0x2a, 0x02, 0x19},
+ {0x33, 0x18, 0x35},
+ {0x2a, 0x20, 0x21},
+ {0x2e, 0x32, 0x1b},
+ {0x3b, 0x1f, 0x23},
+ {0x39, 0x29, 0x2a},
+ {0x2e, 0x31, 0x29},
+ {0x2a, 0x0e, 0x2d},
+ {0x2d, 0x00, 0x1f},
+ {0x38, 0x28, 0x1b},
+ {0x14, 0x3b, 0x2b},
+ {0x2e, 0x04, 0x26},
+ {0x36, 0x30, 0x11},
+ {0x3b, 0x21, 0x2d},
+ {0x2b, 0x3f, 0x1b},
+ {0x20, 0x13, 0x31},
+ {0x33, 0x0c, 0x30},
+ {0x22, 0x2b, 0x2b},
+ {0x16, 0x02, 0x1e},
+ {0x1c, 0x12, 0x1c},
+ {0x0f, 0x3c, 0x36},
+ {0x38, 0x10, 0x2d},
+ {0x18, 0x2f, 0x2d},
+ {0x35, 0x3b, 0x11},
+ {0x37, 0x31, 0x13},
+ {0x13, 0x3d, 0x2f},
+ {0x1e, 0x2c, 0x33},
+ {0x2e, 0x37, 0x12},
+ {0x3c, 0x1f, 0x33},
+ {0x32, 0x2a, 0x27},
+ {0x0d, 0x3b, 0x1c},
+ {0x35, 0x2a, 0x27},
+ {0x09, 0x3d, 0x27},
+ {0x12, 0x0b, 0x18},
+ {0x0c, 0x15, 0x1d},
+ {0x20, 0x01, 0x1c},
+ {0x08, 0x3b, 0x1c},
+ {0x12, 0x37, 0x33},
+ {0x15, 0x03, 0x2c},
+ {0x2a, 0x3b, 0x31},
+ {0x0f, 0x04, 0x35},
+ {0x08, 0x17, 0x33},
+ {0x38, 0x3d, 0x2a},
+ {0x2f, 0x35, 0x16},
+ {0x10, 0x35, 0x16},
+ {0x23, 0x13, 0x2c},
+ {0x2f, 0x06, 0x20},
+ {0x27, 0x3a, 0x24},
+ {0x00, 0x1c, 0x2a},
+ {0x03, 0x39, 0x1d},
+ {0x28, 0x07, 0x1a},
+ {0x20, 0x0a, 0x37},
+ {0x07, 0x35, 0x2d},
+ {0x15, 0x2f, 0x2c},
+ {0x10, 0x2c, 0x23},
+ {0x3f, 0x29, 0x14},
+ {0x2a, 0x21, 0x36},
+ {0x34, 0x1a, 0x2c},
+ {0x1c, 0x3d, 0x33},
+ {0x38, 0x2b, 0x22},
+ {0x35, 0x28, 0x1f},
+ {0x3d, 0x0f, 0x1c},
+ {0x1e, 0x3e, 0x1b},
+ {0x0c, 0x3e, 0x1f},
+ {0x2b, 0x31, 0x2c},
+ {0x32, 0x39, 0x11},
+ {0x05, 0x09, 0x11},
+ {0x04, 0x38, 0x2a},
+ {0x32, 0x00, 0x16},
+ {0x13, 0x0b, 0x31},
+ {0x34, 0x2a, 0x13},
+ {0x2c, 0x22, 0x21},
+ {0x39, 0x2f, 0x15},
+ {0x37, 0x28, 0x1e},
+ {0x07, 0x3b, 0x2d},
+ {0x11, 0x03, 0x28},
+ {0x2d, 0x30, 0x1e},
+ {0x31, 0x11, 0x11},
+ {0x23, 0x01, 0x1e},
+ {0x3d, 0x31, 0x34},
+ {0x1c, 0x02, 0x34},
+ {0x21, 0x0e, 0x25},
+ {0x3d, 0x07, 0x17},
+ {0x33, 0x15, 0x10},
+ {0x29, 0x32, 0x32},
+ {0x18, 0x1f, 0x30},
+ {0x2d, 0x3b, 0x30},
+ {0x27, 0x3e, 0x16},
+ {0x31, 0x15, 0x12},
+ {0x30, 0x25, 0x17},
+ {0x33, 0x06, 0x34},
+ {0x00, 0x29, 0x18},
+ {0x3c, 0x03, 0x12},
+ {0x2c, 0x0c, 0x11},
+ {0x09, 0x30, 0x30},
+ {0x10, 0x0e, 0x11},
+ {0x27, 0x16, 0x1b},
+ {0x0c, 0x3b, 0x2e},
+ {0x2b, 0x33, 0x1e},
+ {0x13, 0x2d, 0x2d},
+ {0x11, 0x24, 0x29},
+ {0x34, 0x3e, 0x2b},
+ {0x24, 0x1e, 0x21},
+ {0x27, 0x1a, 0x2d},
+ {0x04, 0x39, 0x16},
+ {0x3e, 0x33, 0x26},
+ {0x1b, 0x2e, 0x25},
+ {0x0c, 0x06, 0x19},
+ {0x25, 0x19, 0x18},
+ {0x1d, 0x33, 0x33},
+ {0x1d, 0x28, 0x2d},
+ {0x1c, 0x10, 0x2a},
+ {0x1f, 0x35, 0x1e},
+ {0x34, 0x02, 0x10},
+ {0x2b, 0x3a, 0x14},
+ {0x0d, 0x0b, 0x15},
+ {0x0c, 0x2c, 0x10},
+ {0x37, 0x3a, 0x19},
+ {0x06, 0x13, 0x17},
+ {0x24, 0x10, 0x25},
+ {0x24, 0x04, 0x1e},
+ {0x00, 0x35, 0x34},
+ {0x3a, 0x00, 0x37},
+ {0x3c, 0x07, 0x1a},
+ {0x2b, 0x28, 0x36},
+ {0x34, 0x39, 0x2f},
+ {0x28, 0x09, 0x1f},
+ {0x38, 0x31, 0x30},
+ {0x16, 0x25, 0x31},
+ {0x18, 0x28, 0x31},
+ {0x18, 0x0c, 0x22},
+ {0x06, 0x39, 0x2d},
+ {0x3d, 0x20, 0x24},
+ {0x2e, 0x27, 0x21},
+ {0x3e, 0x18, 0x18},
+ {0x15, 0x3c, 0x24},
+ {0x06, 0x1b, 0x26},
+ {0x15, 0x0e, 0x22},
+ {0x0a, 0x0d, 0x1f},
+ {0x18, 0x16, 0x34},
+ {0x10, 0x28, 0x21},
+ {0x20, 0x11, 0x11},
+ {0x36, 0x32, 0x15},
+ {0x3b, 0x2e, 0x24},
+ {0x1f, 0x2d, 0x12},
+ {0x36, 0x2e, 0x20},
+ {0x0b, 0x17, 0x33},
+ {0x26, 0x03, 0x1f},
+ {0x08, 0x19, 0x31},
+ {0x2a, 0x18, 0x25},
+ {0x35, 0x2d, 0x2d},
+ {0x30, 0x38, 0x18},
+ {0x1c, 0x25, 0x14},
+ {0x1c, 0x22, 0x28},
+ {0x08, 0x23, 0x21},
+ {0x26, 0x1e, 0x30},
+ {0x19, 0x0f, 0x15},
+ {0x10, 0x2f, 0x22},
+ {0x12, 0x02, 0x25},
+ {0x3c, 0x01, 0x1d},
+ {0x0e, 0x14, 0x18},
+ {0x0d, 0x18, 0x17},
+ {0x22, 0x0b, 0x31},
+ {0x13, 0x34, 0x21},
+ {0x0f, 0x2d, 0x36},
+ {0x39, 0x1f, 0x25},
+ {0x18, 0x10, 0x1f},
+ {0x2d, 0x20, 0x20},
+ {0x19, 0x0b, 0x31},
+ {0x33, 0x13, 0x14},
+ {0x2e, 0x11, 0x21},
+ {0x2d, 0x0a, 0x37},
+ {0x07, 0x15, 0x1b},
+ {0x32, 0x04, 0x32},
+ {0x06, 0x18, 0x1b},
+ {0x13, 0x24, 0x12},
+ {0x36, 0x22, 0x16},
+ {0x1d, 0x29, 0x1c},
+ {0x35, 0x17, 0x21},
+ {0x36, 0x17, 0x2b},
+ {0x35, 0x32, 0x19},
+ {0x2a, 0x0f, 0x2e},
+ {0x10, 0x00, 0x34},
+ {0x02, 0x0e, 0x28},
+ {0x31, 0x32, 0x32},
+ {0x3b, 0x05, 0x20},
+ {0x36, 0x26, 0x12},
+ {0x34, 0x06, 0x34},
+ {0x1e, 0x31, 0x32},
+ {0x35, 0x05, 0x34},
+ {0x1e, 0x13, 0x15},
+ {0x15, 0x14, 0x2c},
+ {0x29, 0x1c, 0x18},
+ {0x24, 0x24, 0x12},
+ {0x22, 0x29, 0x18},
+ {0x34, 0x36, 0x30},
+ {0x1e, 0x01, 0x23},
+ {0x0c, 0x3c, 0x24},
+ {0x0a, 0x3d, 0x16},
+ {0x27, 0x1e, 0x23},
+ {0x15, 0x02, 0x12},
+ {0x11, 0x19, 0x2a},
+ {0x1d, 0x31, 0x15},
+ {0x03, 0x3b, 0x2a},
+ {0x21, 0x19, 0x2c},
+ {0x0a, 0x23, 0x11},
+ {0x25, 0x11, 0x1a},
+ {0x1a, 0x0a, 0x34},
+ {0x3b, 0x0b, 0x33},
+ {0x21, 0x0b, 0x37},
+ {0x01, 0x31, 0x28},
+ {0x35, 0x1d, 0x27},
+ {0x2c, 0x30, 0x31},
+ {0x2e, 0x39, 0x2d},
+ {0x30, 0x05, 0x2c},
+ {0x12, 0x2a, 0x2b},
+ {0x39, 0x22, 0x20},
+ {0x15, 0x34, 0x1c},
+ {0x1c, 0x01, 0x15},
+ {0x20, 0x16, 0x22},
+ {0x13, 0x04, 0x18},
+ {0x1e, 0x13, 0x10},
+ {0x25, 0x33, 0x15},
+ {0x39, 0x03, 0x31},
+ {0x3f, 0x36, 0x18},
+ {0x14, 0x23, 0x10},
+ {0x2f, 0x1e, 0x1f},
+ {0x1f, 0x17, 0x2c},
+ {0x02, 0x16, 0x31},
+ {0x20, 0x18, 0x30},
+ {0x2e, 0x18, 0x37},
+ {0x3b, 0x0e, 0x30},
+ {0x10, 0x39, 0x24},
+ {0x26, 0x39, 0x1e},
+ {0x30, 0x26, 0x2e},
+ {0x12, 0x01, 0x14},
+ {0x37, 0x2a, 0x2e},
+ {0x21, 0x06, 0x1d},
+ {0x2a, 0x16, 0x32},
+ {0x09, 0x38, 0x1c},
+ {0x07, 0x22, 0x17},
+ {0x3b, 0x2d, 0x15},
+ {0x07, 0x1e, 0x2e},
+ {0x1b, 0x2e, 0x1d},
+ {0x04, 0x09, 0x30},
+ {0x30, 0x2d, 0x37},
+ {0x2d, 0x34, 0x24},
+ {0x18, 0x24, 0x25},
+ {0x0e, 0x2d, 0x26},
+ {0x23, 0x0a, 0x16},
+ {0x12, 0x2d, 0x11},
+ {0x21, 0x28, 0x2e},
+ {0x0f, 0x01, 0x21},
+ {0x01, 0x31, 0x12},
+ {0x3f, 0x1b, 0x1e},
+ {0x21, 0x25, 0x2b},
+ {0x26, 0x18, 0x13},
+ {0x15, 0x2d, 0x34},
+ {0x23, 0x21, 0x36},
+ {0x0e, 0x2e, 0x1c},
+ {0x14, 0x22, 0x1c},
+ {0x2c, 0x0b, 0x28},
+ {0x1a, 0x18, 0x21},
+ {0x21, 0x07, 0x1a},
+ {0x24, 0x26, 0x29},
+ {0x2b, 0x0a, 0x34},
+ {0x3e, 0x27, 0x33},
+ {0x12, 0x34, 0x1b},
+ {0x1f, 0x01, 0x2a},
+ {0x2e, 0x06, 0x23},
+ {0x2f, 0x1f, 0x14},
+ {0x18, 0x06, 0x26},
+ {0x31, 0x1f, 0x2b},
+ {0x22, 0x26, 0x2e},
+ {0x1e, 0x15, 0x16},
+ {0x20, 0x22, 0x28},
+ {0x15, 0x37, 0x12},
+ {0x25, 0x04, 0x2c},
+ {0x1f, 0x04, 0x2e},
+ {0x0c, 0x13, 0x18},
+ {0x07, 0x0b, 0x36},
+ {0x1d, 0x1c, 0x2a},
+ {0x30, 0x22, 0x1c},
+ {0x2e, 0x12, 0x2f},
+ {0x2b, 0x21, 0x1e},
+ {0x16, 0x38, 0x30},
+ {0x04, 0x02, 0x16},
+ {0x05, 0x14, 0x20},
+ {0x38, 0x3c, 0x33},
+ {0x21, 0x1b, 0x2f},
+ {0x14, 0x2a, 0x27},
+ {0x38, 0x14, 0x1b},
+ {0x2b, 0x1f, 0x2b},
+ {0x29, 0x2b, 0x25},
+ {0x27, 0x36, 0x21},
+ {0x11, 0x22, 0x1b},
+ {0x29, 0x03, 0x1b},
+ {0x18, 0x24, 0x28},
+ {0x21, 0x2d, 0x36},
+ {0x3c, 0x2c, 0x24},
+ {0x33, 0x17, 0x1f},
+ {0x2a, 0x3a, 0x21},
+ {0x0a, 0x23, 0x37},
+ {0x00, 0x0b, 0x21},
+ {0x11, 0x38, 0x19},
+ {0x0f, 0x0e, 0x1c},
+ {0x1f, 0x0f, 0x37},
+ {0x3c, 0x10, 0x37},
+ {0x38, 0x31, 0x35},
+ {0x07, 0x15, 0x28},
+ {0x1e, 0x2e, 0x19},
+ {0x26, 0x10, 0x33},
+ {0x3d, 0x35, 0x2f},
+ {0x3a, 0x04, 0x34},
+ {0x0d, 0x18, 0x1a},
+ {0x01, 0x2d, 0x15},
+ {0x3d, 0x1a, 0x17},
+ {0x17, 0x3f, 0x32},
+ {0x0b, 0x21, 0x11},
+ {0x1e, 0x26, 0x2b},
+ {0x0d, 0x19, 0x24},
+ {0x2e, 0x04, 0x1b},
+ {0x1b, 0x33, 0x20},
+ {0x15, 0x21, 0x1d},
+ {0x1f, 0x04, 0x21},
+ {0x0f, 0x12, 0x1f},
+ {0x2d, 0x2a, 0x32},
+ {0x03, 0x37, 0x1f},
+ {0x35, 0x07, 0x27},
+ {0x24, 0x1f, 0x31},
+ {0x2f, 0x30, 0x15},
+ {0x06, 0x00, 0x24},
+ {0x0b, 0x22, 0x1a},
+ {0x0c, 0x3b, 0x29},
+ {0x14, 0x1a, 0x17},
+ {0x37, 0x20, 0x25},
+ {0x3f, 0x26, 0x37},
+ {0x3a, 0x3e, 0x10},
+ {0x22, 0x04, 0x11},
+ {0x28, 0x12, 0x1c},
+ {0x03, 0x2e, 0x2e},
+ {0x0e, 0x38, 0x28},
+ {0x01, 0x29, 0x22},
+ {0x1e, 0x33, 0x19},
+ {0x06, 0x21, 0x27},
+ {0x33, 0x19, 0x1a},
+ {0x02, 0x05, 0x17},
+ {0x11, 0x11, 0x2c},
+ {0x1f, 0x26, 0x1e},
+ {0x39, 0x1f, 0x28},
+ {0x2e, 0x2f, 0x12},
+ {0x22, 0x34, 0x13},
+ {0x3b, 0x26, 0x2f},
+ {0x34, 0x00, 0x14},
+ {0x10, 0x31, 0x11},
+ {0x1d, 0x2d, 0x2a},
+ {0x08, 0x08, 0x37},
+ {0x15, 0x18, 0x34},
+ {0x04, 0x2b, 0x24},
+ {0x2f, 0x1e, 0x27},
+ {0x22, 0x2a, 0x24},
+ {0x07, 0x14, 0x25},
+ {0x01, 0x27, 0x19},
+ {0x29, 0x0a, 0x29},
+ {0x3d, 0x1c, 0x2f},
+ {0x0d, 0x1f, 0x1c},
+ {0x24, 0x3d, 0x32},
+ {0x36, 0x1d, 0x24},
+ {0x14, 0x21, 0x16},
+ {0x1a, 0x0d, 0x29},
+ {0x3f, 0x2b, 0x2a},
+ {0x1a, 0x3e, 0x35},
+ {0x11, 0x28, 0x18},
+ {0x32, 0x05, 0x15},
+ {0x21, 0x2e, 0x34},
+ {0x2d, 0x14, 0x2a},
+ {0x3c, 0x08, 0x37},
+ {0x3f, 0x34, 0x1e},
+ {0x27, 0x24, 0x1c},
+ {0x16, 0x16, 0x33},
+ {0x29, 0x3b, 0x19},
+ {0x36, 0x2f, 0x1c},
+ {0x03, 0x25, 0x2c},
+ {0x0b, 0x16, 0x36},
+ {0x1c, 0x1d, 0x1b},
+ {0x2c, 0x27, 0x1b},
+ {0x0b, 0x1f, 0x2b},
+ {0x08, 0x10, 0x27},
+ {0x3f, 0x25, 0x2f},
+ {0x33, 0x13, 0x1f},
+ {0x04, 0x31, 0x37},
+ {0x0e, 0x2f, 0x12},
+ {0x08, 0x23, 0x20},
+ {0x3a, 0x1a, 0x1e},
+ {0x2f, 0x0b, 0x1f},
+ {0x1e, 0x20, 0x19},
+ {0x23, 0x3b, 0x14},
+ {0x25, 0x00, 0x27},
+ {0x14, 0x04, 0x25},
+ {0x36, 0x1a, 0x2b},
+ {0x27, 0x21, 0x15},
+ {0x28, 0x13, 0x2c},
+ {0x0e, 0x3c, 0x35},
+ {0x0c, 0x2d, 0x2b},
+ {0x37, 0x16, 0x15},
+ {0x29, 0x15, 0x1d},
+ {0x17, 0x34, 0x36},
+ {0x09, 0x0a, 0x31},
+ {0x37, 0x22, 0x28},
+ {0x17, 0x2b, 0x35},
+ {0x14, 0x2b, 0x12},
+ {0x08, 0x13, 0x1f},
+ {0x31, 0x13, 0x28},
+ {0x06, 0x07, 0x35},
+ {0x23, 0x3a, 0x29},
+ {0x0f, 0x24, 0x2e},
+ {0x07, 0x35, 0x26},
+ {0x0e, 0x12, 0x15},
+ {0x23, 0x33, 0x2c},
+ {0x0e, 0x21, 0x26},
+ {0x1c, 0x12, 0x25},
+ {0x23, 0x1d, 0x2f},
+ {0x04, 0x35, 0x33},
+ {0x16, 0x01, 0x24},
+ {0x3d, 0x2c, 0x2e},
+ {0x35, 0x0a, 0x25},
+ {0x11, 0x13, 0x25},
+ {0x1b, 0x1b, 0x15},
+ {0x15, 0x39, 0x10},
+ {0x0b, 0x35, 0x24},
+ {0x3a, 0x27, 0x30},
+ {0x2e, 0x2f, 0x15},
+ {0x10, 0x1f, 0x35},
+ {0x1b, 0x28, 0x35},
+ {0x26, 0x30, 0x37},
+ {0x34, 0x37, 0x2b},
+ {0x0f, 0x30, 0x29},
+ {0x2e, 0x3f, 0x2b},
+ {0x38, 0x34, 0x2b},
+ {0x2b, 0x2f, 0x25},
+ {0x0d, 0x28, 0x2a},
+ {0x33, 0x18, 0x10},
+ {0x21, 0x12, 0x11},
+ {0x1f, 0x22, 0x34},
+ {0x11, 0x25, 0x23},
+ {0x21, 0x3f, 0x11},
+ {0x26, 0x27, 0x25},
+ {0x28, 0x36, 0x12},
+ {0x15, 0x26, 0x32},
+ {0x11, 0x18, 0x24},
+ {0x32, 0x25, 0x37},
+ {0x27, 0x3a, 0x33},
+ {0x35, 0x07, 0x1c},
+ {0x1a, 0x0e, 0x2a},
+ {0x1e, 0x2f, 0x1f},
+ {0x00, 0x2e, 0x21},
+ {0x1b, 0x3c, 0x14},
+ {0x2f, 0x3a, 0x2f},
+ {0x3e, 0x38, 0x15},
+ {0x1a, 0x13, 0x2f},
+ {0x29, 0x0d, 0x2f},
+ {0x37, 0x17, 0x18},
+ {0x30, 0x1c, 0x35},
+ {0x15, 0x34, 0x14},
+ {0x28, 0x11, 0x2c},
+ {0x2c, 0x25, 0x2a},
+ {0x20, 0x3f, 0x28},
+ {0x0c, 0x34, 0x1b},
+ {0x30, 0x2e, 0x25},
+ {0x37, 0x1c, 0x24},
+ {0x1f, 0x25, 0x26},
+ {0x0c, 0x19, 0x34},
+ {0x18, 0x10, 0x35},
+ {0x0a, 0x13, 0x11},
+ {0x25, 0x13, 0x20},
+ {0x13, 0x19, 0x11},
+ {0x20, 0x28, 0x1d},
+ {0x3e, 0x30, 0x1b},
+ {0x23, 0x24, 0x21},
+ {0x0d, 0x23, 0x23},
+ {0x1d, 0x28, 0x2e},
+ {0x2d, 0x12, 0x1f},
+ {0x0e, 0x2e, 0x2b},
+ {0x0b, 0x31, 0x32},
+ {0x24, 0x3c, 0x2c},
+ {0x13, 0x3c, 0x12},
+ {0x28, 0x16, 0x2a},
+ {0x05, 0x0c, 0x32},
+ {0x39, 0x0b, 0x32},
+ {0x21, 0x04, 0x14},
+ {0x10, 0x31, 0x32},
+ {0x12, 0x1f, 0x23},
+ {0x39, 0x2e, 0x2e},
+ {0x22, 0x3d, 0x27},
+ {0x0c, 0x1e, 0x18},
+ {0x25, 0x00, 0x17},
+ {0x06, 0x31, 0x14},
+ {0x13, 0x21, 0x1a},
+ {0x14, 0x20, 0x35},
+ {0x0a, 0x3b, 0x25},
+ {0x33, 0x08, 0x28},
+ {0x3d, 0x02, 0x33},
+ {0x23, 0x00, 0x13},
+ {0x22, 0x21, 0x28},
+ {0x30, 0x14, 0x2e},
+ {0x14, 0x32, 0x36},
+ {0x39, 0x23, 0x1e},
+ {0x1c, 0x11, 0x30},
+ {0x37, 0x16, 0x30},
+ {0x15, 0x31, 0x1f},
+ {0x34, 0x28, 0x2c},
+ {0x35, 0x05, 0x29},
+ {0x37, 0x33, 0x2a},
+ {0x1c, 0x17, 0x2e},
+ {0x10, 0x06, 0x16},
+ {0x32, 0x1f, 0x2f},
+ {0x00, 0x29, 0x1e},
+ {0x04, 0x01, 0x16},
+ {0x3b, 0x23, 0x1e},
+ {0x1b, 0x34, 0x2a},
+ {0x30, 0x11, 0x2b},
+ {0x03, 0x00, 0x1f},
+ {0x1d, 0x37, 0x1a},
+ {0x3a, 0x18, 0x25},
+ {0x1c, 0x16, 0x2c},
+ {0x04, 0x3f, 0x33},
+ {0x26, 0x23, 0x2d},
+ {0x15, 0x2c, 0x27},
+ {0x02, 0x35, 0x27},
+ {0x07, 0x35, 0x33},
+ {0x1a, 0x0c, 0x10},
+ {0x28, 0x26, 0x2c},
+ {0x2f, 0x36, 0x16},
+ {0x37, 0x0b, 0x27},
+ {0x1b, 0x3d, 0x18},
+ {0x27, 0x1f, 0x20},
+ {0x2b, 0x2a, 0x33},
+ {0x0b, 0x0f, 0x20},
+ {0x35, 0x3c, 0x2f},
+ {0x33, 0x21, 0x15},
+ {0x2d, 0x26, 0x34},
+ {0x1f, 0x1a, 0x21},
+ {0x2f, 0x2c, 0x2a},
+ {0x1a, 0x32, 0x1a},
+ {0x3b, 0x3f, 0x21},
+ {0x13, 0x3f, 0x13},
+ {0x0f, 0x24, 0x22},
+ {0x14, 0x1b, 0x10},
+ {0x21, 0x06, 0x28},
+ {0x25, 0x34, 0x10},
+ {0x2e, 0x0e, 0x14},
+ {0x3c, 0x3e, 0x25},
+ {0x16, 0x06, 0x30},
+ {0x0b, 0x04, 0x1f},
+ {0x3e, 0x02, 0x24},
+ {0x0c, 0x17, 0x25},
+ {0x2b, 0x3c, 0x2d},
+ {0x15, 0x36, 0x33},
+ {0x18, 0x23, 0x2a},
+ {0x1d, 0x10, 0x2a},
+ {0x35, 0x17, 0x28},
+ {0x00, 0x37, 0x24},
+ {0x0a, 0x3b, 0x15},
+ {0x1d, 0x0b, 0x1f},
+ {0x3c, 0x31, 0x25},
+ {0x1d, 0x0f, 0x1d},
+ {0x20, 0x13, 0x34},
+ {0x11, 0x2b, 0x2e},
+ {0x23, 0x0c, 0x2e},
+ {0x24, 0x02, 0x14},
+ {0x31, 0x16, 0x19},
+ {0x0e, 0x23, 0x35},
+ {0x1a, 0x10, 0x16},
+ {0x14, 0x04, 0x19},
+ {0x2d, 0x27, 0x37},
+ {0x33, 0x02, 0x31},
+ {0x02, 0x04, 0x16},
+ {0x0d, 0x22, 0x25},
+ {0x25, 0x00, 0x16},
+ {0x2a, 0x3f, 0x26},
+ {0x20, 0x0c, 0x12},
+ {0x2f, 0x2e, 0x35},
+ {0x1b, 0x0d, 0x22},
+ {0x1e, 0x01, 0x34},
+ {0x05, 0x22, 0x21},
+ {0x34, 0x2a, 0x32},
+ {0x0b, 0x09, 0x1d},
+ {0x3f, 0x32, 0x2f},
+ {0x3d, 0x18, 0x2d},
+ {0x0b, 0x38, 0x36},
+ {0x39, 0x17, 0x28},
+ {0x34, 0x04, 0x24},
+ {0x36, 0x0e, 0x2a},
+ {0x38, 0x01, 0x14},
+ {0x3c, 0x24, 0x22},
+ {0x21, 0x03, 0x18},
+ {0x32, 0x2f, 0x12},
+ {0x29, 0x24, 0x31},
+ {0x0a, 0x3b, 0x12},
+ {0x1a, 0x1c, 0x20},
+ {0x30, 0x31, 0x1b},
+ {0x1a, 0x21, 0x10},
+ {0x05, 0x29, 0x10},
+ {0x26, 0x2d, 0x13},
+ {0x16, 0x0c, 0x1d},
+ {0x2b, 0x06, 0x1b},
+ {0x06, 0x12, 0x14},
+ {0x38, 0x0f, 0x35},
+ {0x23, 0x3a, 0x2c},
+ {0x00, 0x19, 0x33},
+ {0x29, 0x14, 0x2d},
+ {0x2a, 0x21, 0x29},
+ {0x14, 0x31, 0x14},
+ {0x1a, 0x06, 0x1e},
+ {0x18, 0x1b, 0x28},
+ {0x3b, 0x16, 0x29},
+ {0x15, 0x1e, 0x12},
+ {0x34, 0x0a, 0x14},
+ {0x1b, 0x05, 0x27},
+ {0x0b, 0x01, 0x26},
+ {0x2a, 0x22, 0x35},
+ {0x21, 0x20, 0x18},
+ {0x20, 0x37, 0x17},
+ {0x14, 0x1f, 0x11},
+ {0x1d, 0x11, 0x25},
+ {0x24, 0x2b, 0x2f},
+ {0x07, 0x3f, 0x1f},
+ {0x2c, 0x25, 0x25},
+ {0x2a, 0x29, 0x18},
+ {0x11, 0x24, 0x28},
+ {0x31, 0x2c, 0x2a},
+ {0x39, 0x0b, 0x26},
+ {0x28, 0x10, 0x26},
+ {0x22, 0x06, 0x16},
+ {0x09, 0x2c, 0x13},
+ {0x34, 0x19, 0x15},
+ {0x3a, 0x12, 0x21},
+ {0x1d, 0x38, 0x23},
+ {0x12, 0x25, 0x24},
+ {0x21, 0x30, 0x12},
+ {0x37, 0x1a, 0x12},
+ {0x24, 0x3b, 0x25},
+ {0x32, 0x15, 0x23},
+ {0x0d, 0x1a, 0x10},
+ {0x16, 0x2e, 0x26},
+ {0x1d, 0x14, 0x16},
+ {0x3e, 0x2e, 0x1f},
+ {0x0a, 0x16, 0x10},
+ {0x1d, 0x30, 0x2b},
+ {0x04, 0x3a, 0x19},
+ {0x08, 0x2d, 0x2e},
+ {0x28, 0x1e, 0x33},
+ {0x0a, 0x12, 0x2e},
+ {0x0d, 0x03, 0x2f},
+ {0x26, 0x3a, 0x1e},
+ {0x35, 0x3b, 0x2a},
+ {0x03, 0x1a, 0x18},
+ {0x3f, 0x0b, 0x27},
+ {0x04, 0x05, 0x34},
+ {0x36, 0x0b, 0x27},
+ {0x3b, 0x17, 0x11},
+ {0x0d, 0x27, 0x26},
+ {0x2c, 0x1f, 0x20},
+ {0x26, 0x10, 0x20},
+ {0x25, 0x23, 0x2d},
+ {0x37, 0x09, 0x13},
+ {0x14, 0x17, 0x2d},
+ {0x2e, 0x3d, 0x23},
+ {0x1d, 0x1a, 0x1f},
+ {0x21, 0x33, 0x2e},
+ {0x28, 0x17, 0x13},
+ {0x26, 0x3c, 0x36},
+ {0x14, 0x1a, 0x33},
+ {0x32, 0x20, 0x2b},
+ {0x19, 0x3e, 0x20},
+ {0x0c, 0x02, 0x2d},
+ {0x3c, 0x3c, 0x2a},
+ {0x30, 0x30, 0x28},
+ {0x25, 0x3f, 0x1e},
+ {0x03, 0x17, 0x1e},
+ {0x35, 0x11, 0x1c},
+ {0x1b, 0x14, 0x2a},
+ {0x28, 0x3a, 0x23},
+ {0x0e, 0x1f, 0x12},
+ {0x36, 0x21, 0x20},
+ {0x07, 0x3b, 0x10},
+ {0x23, 0x19, 0x34},
+ {0x0d, 0x2e, 0x18},
+ {0x3f, 0x20, 0x25},
+ {0x3e, 0x3b, 0x15},
+ {0x0b, 0x2e, 0x12},
+ {0x37, 0x0b, 0x23},
+ {0x3d, 0x32, 0x1f},
+ {0x16, 0x03, 0x27},
+ {0x14, 0x0c, 0x21},
+ {0x18, 0x03, 0x30},
+ {0x3e, 0x21, 0x13},
+ {0x0f, 0x00, 0x32},
+ {0x3f, 0x23, 0x16},
+ {0x0e, 0x31, 0x1d},
+ {0x18, 0x1c, 0x1d},
+ {0x30, 0x0e, 0x1e},
+ {0x21, 0x20, 0x23},
+ {0x3f, 0x0c, 0x1e},
+ {0x14, 0x33, 0x22},
+ {0x22, 0x21, 0x15},
+ {0x36, 0x05, 0x1e},
+ {0x1d, 0x31, 0x14},
+ {0x20, 0x11, 0x37},
+ {0x0d, 0x33, 0x19},
+ {0x25, 0x05, 0x36},
+ {0x1e, 0x31, 0x20},
+ {0x35, 0x3a, 0x2f},
+ {0x32, 0x2f, 0x30},
+ {0x14, 0x23, 0x2d},
+ {0x35, 0x1e, 0x29},
+ {0x05, 0x05, 0x1b},
+ {0x09, 0x1f, 0x26},
+ {0x2f, 0x0b, 0x15},
+ {0x15, 0x11, 0x13},
+ {0x29, 0x1b, 0x18},
+ {0x1c, 0x13, 0x35},
+ {0x34, 0x31, 0x23},
+ {0x27, 0x3f, 0x2f},
+ {0x09, 0x30, 0x19},
+ {0x23, 0x12, 0x34},
+ {0x02, 0x2a, 0x21},
+ {0x09, 0x3c, 0x1d},
+ {0x0c, 0x02, 0x10},
+ {0x22, 0x05, 0x17},
+ {0x22, 0x08, 0x1b},
+ {0x0a, 0x0f, 0x15},
+ {0x02, 0x11, 0x13},
+ {0x01, 0x21, 0x22},
+ {0x16, 0x39, 0x33},
+ {0x24, 0x38, 0x34},
+ {0x0f, 0x1e, 0x2b},
+ {0x2b, 0x15, 0x15},
+ {0x20, 0x22, 0x2e},
+ {0x3a, 0x3f, 0x31},
+ {0x1a, 0x27, 0x2b},
+ {0x29, 0x34, 0x14},
+ {0x16, 0x39, 0x2f},
+ {0x13, 0x3e, 0x16},
+ {0x36, 0x21, 0x30},
+ {0x00, 0x24, 0x2b},
+ {0x24, 0x21, 0x30},
+ {0x15, 0x31, 0x13},
+ {0x10, 0x37, 0x24},
+ {0x08, 0x07, 0x23},
+ {0x21, 0x09, 0x25},
+ {0x05, 0x3c, 0x32},
+ {0x19, 0x03, 0x25},
+ {0x0f, 0x29, 0x2b},
+ {0x16, 0x07, 0x13},
+ {0x3e, 0x3d, 0x25},
+ {0x36, 0x0b, 0x28},
+ {0x2e, 0x2b, 0x16},
+ {0x0c, 0x31, 0x11},
+ {0x30, 0x13, 0x2d},
+ {0x26, 0x3e, 0x37},
+ {0x29, 0x2f, 0x2e},
+ {0x15, 0x3d, 0x17},
+ {0x1c, 0x2e, 0x21},
+ {0x33, 0x2f, 0x10},
+ {0x0d, 0x05, 0x1d},
+ {0x1c, 0x1a, 0x12},
+ {0x0e, 0x18, 0x37},
+ {0x1b, 0x11, 0x14},
+ {0x06, 0x14, 0x21},
+ {0x31, 0x0e, 0x27},
+ {0x1a, 0x03, 0x10},
+ {0x00, 0x34, 0x31},
+ {0x3f, 0x0b, 0x1d},
+ {0x0f, 0x12, 0x1f},
+ {0x1a, 0x15, 0x10},
+ {0x0f, 0x00, 0x24},
+ {0x3e, 0x0a, 0x2a},
+ {0x30, 0x2b, 0x24},
+ {0x26, 0x31, 0x10},
+ {0x2d, 0x2f, 0x2f},
+ {0x3f, 0x0c, 0x13},
+ {0x12, 0x0b, 0x16},
+ {0x15, 0x07, 0x1f},
+ {0x28, 0x10, 0x32},
+ {0x0f, 0x17, 0x15},
+ {0x0b, 0x27, 0x33},
+ {0x34, 0x1d, 0x10},
+ {0x1c, 0x3a, 0x12},
+ {0x2c, 0x27, 0x37},
+ {0x0a, 0x1a, 0x32},
+ {0x05, 0x1f, 0x21},
+ {0x24, 0x0d, 0x1f},
+ {0x1c, 0x17, 0x24},
+ {0x2f, 0x3b, 0x32},
+ {0x3b, 0x25, 0x10},
+ {0x03, 0x2f, 0x21},
+ {0x0c, 0x10, 0x23},
+ {0x0e, 0x3a, 0x2c},
+ {0x33, 0x03, 0x2c},
+ {0x12, 0x06, 0x1c},
+ {0x2a, 0x37, 0x30},
+ {0x3f, 0x01, 0x1e},
+ {0x35, 0x16, 0x37},
+ {0x2c, 0x32, 0x35},
+ {0x05, 0x11, 0x22},
+ {0x29, 0x09, 0x20},
+ {0x2b, 0x0d, 0x1f},
+ {0x18, 0x0d, 0x20},
+ {0x23, 0x39, 0x16},
+ {0x0f, 0x3a, 0x18},
+ {0x21, 0x35, 0x2b},
+ {0x36, 0x26, 0x2b},
+ {0x23, 0x05, 0x2f},
+ {0x1b, 0x08, 0x17},
+ {0x3e, 0x09, 0x16},
+ {0x2d, 0x3a, 0x37},
+ {0x15, 0x35, 0x35},
+ {0x29, 0x0a, 0x12},
+ {0x02, 0x39, 0x1f},
+ {0x14, 0x34, 0x33},
+ {0x17, 0x1d, 0x18},
+ {0x16, 0x1d, 0x1a},
+ {0x01, 0x39, 0x22},
+ {0x1e, 0x27, 0x36},
+ {0x32, 0x14, 0x26},
+ {0x0a, 0x39, 0x36},
+ {0x1f, 0x0d, 0x1e},
+ {0x0b, 0x0a, 0x19},
+ {0x35, 0x1d, 0x34},
+ {0x03, 0x12, 0x16},
+ {0x0c, 0x13, 0x2e},
+ {0x0c, 0x34, 0x1e},
+ {0x10, 0x14, 0x1e},
+ {0x23, 0x32, 0x27},
+ {0x02, 0x10, 0x29},
+ {0x35, 0x18, 0x33},
+ {0x33, 0x1d, 0x1a},
+ {0x3c, 0x15, 0x23},
+ {0x3e, 0x3f, 0x22},
+ {0x2a, 0x02, 0x2c},
+ {0x28, 0x0a, 0x2f},
+ {0x1a, 0x06, 0x35},
+ {0x3c, 0x17, 0x2b},
+ {0x03, 0x12, 0x17},
+ {0x2f, 0x0a, 0x26},
+ {0x12, 0x38, 0x11},
+ {0x36, 0x1b, 0x23},
+ {0x01, 0x39, 0x35},
+ {0x19, 0x19, 0x17},
+ {0x09, 0x28, 0x22},
+ {0x1e, 0x27, 0x2c},
+ {0x35, 0x33, 0x2c},
+ {0x27, 0x25, 0x31},
+ {0x06, 0x31, 0x2d},
+ {0x1a, 0x39, 0x28},
+ {0x2d, 0x04, 0x1e},
+ {0x24, 0x3e, 0x1c},
+ {0x3c, 0x30, 0x1b},
+ {0x3f, 0x3e, 0x37},
+ {0x22, 0x36, 0x11},
+ {0x00, 0x01, 0x1c},
+ {0x12, 0x1a, 0x10},
+ {0x12, 0x1e, 0x2c},
+ {0x1f, 0x12, 0x2a},
+ {0x2f, 0x06, 0x19},
+ {0x35, 0x1a, 0x18},
+ {0x3b, 0x09, 0x36},
+ {0x34, 0x1d, 0x13},
+ {0x02, 0x07, 0x10},
+ {0x20, 0x2f, 0x1d},
+ {0x0b, 0x03, 0x33},
+ {0x1c, 0x16, 0x31},
+ {0x05, 0x13, 0x1b},
+ {0x29, 0x06, 0x13},
+ {0x30, 0x2d, 0x36},
+ {0x2a, 0x2d, 0x2c},
+ {0x19, 0x34, 0x1c},
+ {0x0f, 0x15, 0x12},
+ {0x36, 0x15, 0x2c},
+ {0x3a, 0x06, 0x1c},
+ {0x12, 0x1d, 0x26},
+ {0x03, 0x38, 0x1d},
+ {0x01, 0x01, 0x2d},
+ {0x17, 0x2e, 0x10},
+ {0x14, 0x17, 0x1c},
+ {0x34, 0x0f, 0x28},
+ {0x09, 0x37, 0x1b},
+ {0x28, 0x1d, 0x26},
+ {0x29, 0x2d, 0x36},
+ {0x1e, 0x17, 0x28},
+ {0x15, 0x0f, 0x1c},
+ {0x20, 0x2d, 0x10},
+ {0x27, 0x16, 0x2e},
+ {0x14, 0x09, 0x12},
+ {0x3b, 0x3d, 0x21},
+ {0x25, 0x1a, 0x2c},
+ {0x00, 0x22, 0x36},
+ {0x0d, 0x30, 0x10},
+ {0x17, 0x19, 0x1b},
+ {0x00, 0x3b, 0x21},
+ {0x2a, 0x28, 0x34},
+ {0x2d, 0x0f, 0x16},
+ {0x0a, 0x30, 0x28},
+ {0x06, 0x00, 0x25},
+ {0x31, 0x2e, 0x2a},
+ {0x14, 0x33, 0x28},
+ {0x36, 0x10, 0x2e},
+ {0x05, 0x2e, 0x19},
+ {0x19, 0x1a, 0x15},
+ {0x2c, 0x14, 0x17},
+ {0x37, 0x0f, 0x13},
+ {0x32, 0x17, 0x1b},
+ {0x39, 0x18, 0x32},
+ {0x2e, 0x32, 0x1e},
+ {0x24, 0x1d, 0x31},
+ {0x12, 0x1d, 0x2b},
+ {0x14, 0x0c, 0x27},
+ {0x36, 0x2e, 0x32},
+ {0x06, 0x0a, 0x1a},
+ {0x28, 0x28, 0x20},
+ {0x3a, 0x3a, 0x17},
+ {0x08, 0x27, 0x36},
+ {0x18, 0x1a, 0x10},
+ {0x1e, 0x26, 0x1b},
+ {0x1f, 0x33, 0x1f},
+ {0x21, 0x17, 0x2f},
+ {0x01, 0x08, 0x20},
+ {0x35, 0x03, 0x19},
+ {0x3b, 0x02, 0x20},
+ {0x02, 0x2d, 0x23},
+ {0x0e, 0x17, 0x32},
+ {0x31, 0x29, 0x11},
+ {0x22, 0x17, 0x22},
+ {0x3a, 0x2c, 0x23},
+ {0x34, 0x20, 0x18},
+ {0x00, 0x3a, 0x22},
+ {0x25, 0x33, 0x21},
+ {0x33, 0x04, 0x27},
+ {0x04, 0x18, 0x32},
+ {0x2c, 0x0c, 0x2f},
+ {0x28, 0x14, 0x2c},
+ {0x3f, 0x30, 0x2b},
+ {0x30, 0x21, 0x1d},
+ {0x01, 0x25, 0x32},
+ {0x05, 0x23, 0x34},
+ {0x24, 0x10, 0x30},
+ {0x3d, 0x14, 0x1b},
+ {0x3f, 0x38, 0x2f},
+ {0x22, 0x1b, 0x32},
+ {0x25, 0x07, 0x37},
+ {0x0a, 0x0c, 0x1d},
+ {0x03, 0x1e, 0x1a},
+ {0x0f, 0x3c, 0x12},
+ {0x11, 0x18, 0x1d},
+ {0x00, 0x35, 0x2f},
+ {0x32, 0x18, 0x14},
+ {0x23, 0x30, 0x1b},
+ {0x11, 0x3d, 0x12},
+ {0x1a, 0x16, 0x35},
+ {0x28, 0x05, 0x24},
+ {0x17, 0x3d, 0x37},
+ {0x2e, 0x09, 0x2e},
+ {0x18, 0x1d, 0x17},
+ {0x20, 0x1f, 0x18},
+ {0x23, 0x2c, 0x2f},
+ {0x20, 0x3f, 0x16},
+ {0x3f, 0x29, 0x2e},
+ {0x23, 0x3b, 0x29},
+ {0x18, 0x39, 0x13},
+ {0x1e, 0x32, 0x35},
+ {0x14, 0x1d, 0x2a},
+ {0x35, 0x01, 0x1d},
+ {0x3e, 0x3b, 0x1e},
+ {0x22, 0x1e, 0x16},
+ {0x18, 0x22, 0x12},
+ {0x3e, 0x29, 0x33},
+ {0x2f, 0x14, 0x19},
+ {0x3b, 0x07, 0x15},
+ {0x06, 0x3d, 0x29},
+ {0x35, 0x37, 0x23},
+ {0x34, 0x1d, 0x2d},
+ {0x18, 0x12, 0x1b},
+ {0x0b, 0x13, 0x24},
+ {0x13, 0x38, 0x1c},
+ {0x1f, 0x0b, 0x1b},
+ {0x13, 0x21, 0x1c},
+ {0x06, 0x39, 0x32},
+ {0x37, 0x3d, 0x26},
+ {0x29, 0x26, 0x15},
+ {0x3c, 0x33, 0x27},
+ {0x00, 0x01, 0x2e},
+ {0x15, 0x18, 0x31},
+ {0x0d, 0x2c, 0x13},
+ {0x27, 0x3b, 0x20},
+ {0x2d, 0x01, 0x26},
+ {0x23, 0x15, 0x30},
+ {0x24, 0x00, 0x17},
+ {0x37, 0x3f, 0x33},
+ {0x25, 0x24, 0x31},
+ {0x06, 0x3b, 0x37},
+ {0x03, 0x18, 0x1a},
+ {0x2c, 0x34, 0x14},
+ {0x1d, 0x36, 0x18},
+ {0x3a, 0x04, 0x23},
+ {0x12, 0x26, 0x15},
+ {0x2b, 0x19, 0x1a},
+ {0x29, 0x2c, 0x36},
+ {0x01, 0x19, 0x1d},
+ {0x2f, 0x06, 0x2b},
+ {0x0c, 0x12, 0x26},
+ {0x36, 0x32, 0x1d},
+ {0x0d, 0x12, 0x28},
+ {0x03, 0x28, 0x13},
+ {0x29, 0x06, 0x17},
+ {0x03, 0x38, 0x21},
+ {0x30, 0x2c, 0x10},
+ {0x22, 0x00, 0x28},
+ {0x24, 0x3b, 0x1c},
+ {0x20, 0x3e, 0x13},
+ {0x02, 0x0c, 0x19},
+ {0x29, 0x2c, 0x1a},
+ {0x39, 0x30, 0x22},
+ {0x2a, 0x1f, 0x22},
+ {0x14, 0x34, 0x2c},
+ {0x14, 0x25, 0x1b},
+ {0x06, 0x3b, 0x15},
+ {0x06, 0x1c, 0x13},
+ {0x15, 0x03, 0x18},
+ {0x1e, 0x2a, 0x1b},
+ {0x17, 0x25, 0x2f},
+ {0x1c, 0x29, 0x2e},
+ {0x02, 0x32, 0x1e},
+ {0x1d, 0x28, 0x35},
+ {0x36, 0x03, 0x34},
+ {0x16, 0x3d, 0x2a},
+ {0x12, 0x0d, 0x13},
+ {0x1d, 0x2d, 0x21},
+ {0x32, 0x17, 0x2e},
+ {0x1a, 0x15, 0x26},
+ {0x22, 0x2f, 0x15},
+ {0x3c, 0x0e, 0x20},
+ {0x2f, 0x27, 0x13},
+ {0x04, 0x09, 0x32},
+ {0x1e, 0x01, 0x34},
+ {0x06, 0x16, 0x1e},
+ {0x2e, 0x1b, 0x1c},
+ {0x28, 0x13, 0x2a},
+ {0x30, 0x34, 0x12},
+ {0x12, 0x32, 0x18},
+ {0x1d, 0x1d, 0x35},
+ {0x07, 0x1c, 0x16},
+ {0x2d, 0x3d, 0x35},
+ {0x1c, 0x1b, 0x24},
+ {0x21, 0x2d, 0x1e},
+ {0x10, 0x09, 0x14},
+ {0x3d, 0x11, 0x12},
+ {0x25, 0x02, 0x26},
+ {0x23, 0x02, 0x19},
+ {0x19, 0x05, 0x14},
+ {0x0b, 0x21, 0x1a},
+ {0x09, 0x02, 0x2c},
+ {0x18, 0x28, 0x2d},
+ {0x1e, 0x10, 0x12},
+ {0x2e, 0x18, 0x2e},
+ {0x1f, 0x02, 0x2c},
+ {0x14, 0x17, 0x24},
+ {0x39, 0x08, 0x32},
+ {0x16, 0x14, 0x22},
+ {0x16, 0x28, 0x21},
+ {0x11, 0x10, 0x2c},
+ {0x23, 0x36, 0x2b},
+ {0x39, 0x21, 0x26},
+ {0x0e, 0x06, 0x2d},
+ {0x3c, 0x3e, 0x26},
+ {0x2a, 0x1b, 0x1f},
+ {0x00, 0x3c, 0x33},
+ {0x35, 0x3f, 0x14},
+ {0x00, 0x0b, 0x10},
+ {0x34, 0x3c, 0x17},
+ {0x2d, 0x07, 0x1f},
+ {0x24, 0x39, 0x27},
+ {0x16, 0x00, 0x1d},
+ {0x33, 0x2b, 0x1e},
+ {0x0f, 0x08, 0x31},
+ {0x3a, 0x09, 0x13},
+ {0x0c, 0x21, 0x1c},
+ {0x2a, 0x17, 0x34},
+ {0x29, 0x27, 0x10},
+ {0x37, 0x1b, 0x18},
+ {0x15, 0x08, 0x2f},
+ {0x1f, 0x16, 0x12},
+ {0x1f, 0x28, 0x34},
+ {0x1c, 0x20, 0x22},
+ {0x12, 0x01, 0x12},
+ {0x21, 0x31, 0x10},
+ {0x22, 0x26, 0x1e},
+ {0x01, 0x3d, 0x11},
+ {0x1e, 0x27, 0x25},
+ {0x3d, 0x30, 0x24},
+ {0x1d, 0x11, 0x22},
+ {0x36, 0x30, 0x16},
+ {0x1f, 0x3e, 0x2a},
+ {0x3c, 0x27, 0x1b},
+ {0x1f, 0x29, 0x10},
+ {0x1e, 0x05, 0x2a},
+ {0x0a, 0x10, 0x14},
+ {0x1f, 0x00, 0x2e},
+ {0x0b, 0x3b, 0x18},
+ {0x0a, 0x39, 0x30},
+ {0x37, 0x0b, 0x1f},
+ {0x1d, 0x0a, 0x29},
+ {0x3e, 0x1c, 0x33},
+ {0x13, 0x2e, 0x28},
+ {0x27, 0x1b, 0x1e},
+ {0x1d, 0x02, 0x1c},
+ {0x01, 0x25, 0x14},
+ {0x3a, 0x10, 0x1c},
+ {0x12, 0x05, 0x2a},
+ {0x30, 0x20, 0x26},
+ {0x2f, 0x2e, 0x2e},
+ {0x03, 0x07, 0x24},
+ {0x36, 0x04, 0x2b},
+ {0x11, 0x25, 0x2d},
+ {0x28, 0x0e, 0x2e},
+ {0x0f, 0x1d, 0x15},
+ {0x1c, 0x28, 0x30},
+ {0x1f, 0x23, 0x26},
+ {0x36, 0x12, 0x37},
+ {0x3a, 0x31, 0x10},
+ {0x2c, 0x2c, 0x2f},
+ {0x1a, 0x0d, 0x15},
+ {0x3f, 0x3c, 0x32},
+ {0x35, 0x1c, 0x16},
+ {0x33, 0x16, 0x28},
+ {0x1d, 0x3f, 0x21},
+ {0x2c, 0x3e, 0x2b},
+ {0x24, 0x23, 0x2f},
+ {0x32, 0x15, 0x2a},
+ {0x1b, 0x10, 0x35},
+ {0x18, 0x37, 0x10},
+ {0x3b, 0x1e, 0x11},
+ {0x2b, 0x16, 0x24},
+ {0x1d, 0x16, 0x26},
+ {0x3c, 0x2d, 0x11},
+ {0x15, 0x28, 0x28},
+ {0x27, 0x27, 0x27},
+ {0x3b, 0x3a, 0x16},
+ {0x1a, 0x0c, 0x1a},
+ {0x15, 0x08, 0x25},
+ {0x0b, 0x10, 0x22},
+ {0x1a, 0x3e, 0x17},
+ {0x28, 0x1f, 0x1e},
+ {0x01, 0x1e, 0x1e},
+ {0x1c, 0x2f, 0x10},
+ {0x25, 0x0b, 0x34},
+ {0x3e, 0x0c, 0x1a},
+ {0x1b, 0x10, 0x2a},
+ {0x0f, 0x14, 0x17},
+ {0x0f, 0x3f, 0x17},
+ {0x03, 0x15, 0x1f},
+ {0x02, 0x36, 0x17},
+ {0x15, 0x1d, 0x18},
+ {0x08, 0x36, 0x10},
+ {0x14, 0x0d, 0x2b},
+ {0x0a, 0x05, 0x1d},
+ {0x26, 0x12, 0x1e},
+ {0x3e, 0x18, 0x19},
+ {0x36, 0x18, 0x37},
+ {0x17, 0x39, 0x2e},
+ {0x0d, 0x04, 0x19},
+ {0x16, 0x22, 0x15},
+ {0x3e, 0x26, 0x1f},
+ {0x00, 0x06, 0x17},
+ {0x33, 0x22, 0x1d},
+ {0x2b, 0x39, 0x2b},
+ {0x3e, 0x31, 0x1c},
+ {0x22, 0x3f, 0x13},
+ {0x30, 0x1c, 0x31},
+ {0x07, 0x2b, 0x14},
+ {0x32, 0x35, 0x1e},
+ {0x02, 0x07, 0x20},
+ {0x0f, 0x3b, 0x11},
+ {0x20, 0x07, 0x12},
+ {0x2a, 0x30, 0x1d},
+ {0x28, 0x38, 0x36},
+ {0x20, 0x01, 0x17},
+ {0x15, 0x20, 0x21},
+ {0x3a, 0x1b, 0x1e},
+ {0x38, 0x12, 0x24},
+ {0x03, 0x3e, 0x1f},
+ {0x29, 0x1d, 0x13},
+ {0x20, 0x27, 0x19},
+ {0x12, 0x25, 0x20},
+ {0x32, 0x33, 0x2b},
+ {0x3f, 0x05, 0x31},
+ {0x35, 0x3c, 0x2d},
+ {0x2d, 0x02, 0x2e},
+ {0x10, 0x2a, 0x16},
+ {0x17, 0x08, 0x31},
+ {0x17, 0x2e, 0x2b},
+ {0x30, 0x1e, 0x15},
+ {0x31, 0x15, 0x26},
+ {0x08, 0x10, 0x33},
+ {0x15, 0x01, 0x27},
+ {0x12, 0x07, 0x2f},
+ {0x29, 0x27, 0x34},
+ {0x3f, 0x08, 0x31},
+ {0x1c, 0x20, 0x1a},
+ {0x33, 0x0c, 0x13},
+ {0x18, 0x31, 0x24},
+ {0x37, 0x2d, 0x2e},
+ {0x21, 0x18, 0x24},
+ {0x3a, 0x27, 0x31},
+ {0x35, 0x3e, 0x30},
+ {0x3a, 0x14, 0x33},
+ {0x0f, 0x1a, 0x2d},
+ {0x30, 0x2e, 0x11},
+ {0x1a, 0x31, 0x1d},
+ {0x17, 0x3c, 0x18},
+ {0x33, 0x31, 0x23},
+ {0x1d, 0x39, 0x2d},
+ {0x10, 0x1d, 0x2f},
+ {0x24, 0x15, 0x1c},
+ {0x25, 0x01, 0x2b},
+ {0x22, 0x16, 0x2e},
+ {0x1b, 0x25, 0x35},
+ {0x37, 0x10, 0x26},
+ {0x39, 0x01, 0x36},
+ {0x17, 0x2b, 0x14},
+ {0x09, 0x16, 0x17},
+ {0x20, 0x28, 0x23},
+ {0x26, 0x3a, 0x26},
+ {0x27, 0x2a, 0x24},
+ {0x36, 0x02, 0x2c},
+ {0x29, 0x30, 0x35},
+ {0x36, 0x01, 0x1f},
+ {0x28, 0x3b, 0x1d},
+ {0x23, 0x1e, 0x2d},
+ {0x11, 0x1e, 0x2c},
+ {0x2f, 0x32, 0x19},
+ {0x3f, 0x26, 0x31},
+ {0x38, 0x1e, 0x17},
+ {0x05, 0x18, 0x2e},
+ {0x00, 0x2e, 0x12},
+ {0x34, 0x3f, 0x34},
+ {0x16, 0x10, 0x29},
+ {0x20, 0x3d, 0x36},
+ {0x2f, 0x16, 0x25},
+ {0x12, 0x17, 0x10},
+ {0x21, 0x37, 0x35},
+ {0x25, 0x37, 0x2d},
+ {0x01, 0x08, 0x27},
+ {0x03, 0x1f, 0x29},
+ {0x0d, 0x2a, 0x16},
+ {0x3a, 0x3f, 0x33},
+ {0x2b, 0x19, 0x1d},
+ {0x2a, 0x1f, 0x29},
+ {0x28, 0x2c, 0x10},
+ {0x28, 0x30, 0x10},
+ {0x39, 0x14, 0x1b},
+ {0x00, 0x18, 0x21},
+ {0x28, 0x0c, 0x37},
+ {0x11, 0x10, 0x11},
+ {0x3c, 0x33, 0x32},
+ {0x33, 0x36, 0x1a},
+ {0x36, 0x00, 0x1c},
+ {0x31, 0x1b, 0x1d},
+ {0x38, 0x1d, 0x10},
+ {0x3c, 0x39, 0x27},
+ {0x3a, 0x3f, 0x14},
+ {0x19, 0x12, 0x14},
+ {0x0d, 0x1f, 0x18},
+ {0x00, 0x25, 0x18},
+ {0x28, 0x1c, 0x32},
+ {0x27, 0x03, 0x1a},
+ {0x26, 0x2d, 0x2a},
+ {0x29, 0x28, 0x27},
+ {0x0a, 0x2a, 0x18},
+ {0x0a, 0x1a, 0x30},
+ {0x20, 0x1a, 0x2e},
+ {0x06, 0x0b, 0x1d},
+ {0x0f, 0x0c, 0x1c},
+ {0x35, 0x28, 0x1c},
+ {0x3d, 0x16, 0x23},
+ {0x21, 0x1c, 0x31},
+ {0x14, 0x1c, 0x2e},
+ {0x22, 0x32, 0x35},
+ {0x09, 0x29, 0x30},
+ {0x20, 0x1a, 0x10},
+ {0x31, 0x3f, 0x2c},
+ {0x0a, 0x3d, 0x37},
+ {0x0b, 0x2e, 0x2d},
+ {0x1f, 0x22, 0x31},
+ {0x06, 0x07, 0x29},
+ {0x22, 0x17, 0x2d},
+ {0x30, 0x11, 0x18},
+ {0x0c, 0x19, 0x15},
+ {0x07, 0x0a, 0x34},
+ {0x18, 0x29, 0x27},
+ {0x33, 0x0c, 0x30},
+ {0x03, 0x1a, 0x37},
+ {0x06, 0x01, 0x2d},
+ {0x0f, 0x3b, 0x2b},
+ {0x11, 0x1f, 0x37},
+ {0x2b, 0x21, 0x36},
+ {0x3f, 0x23, 0x17},
+ {0x17, 0x07, 0x2b},
+ {0x2b, 0x0e, 0x30},
+ {0x11, 0x39, 0x1d},
+ {0x29, 0x03, 0x33},
+ {0x30, 0x03, 0x2f},
+ {0x3c, 0x20, 0x26},
+ {0x03, 0x22, 0x14},
+ {0x3a, 0x28, 0x35},
+ {0x01, 0x28, 0x2b},
+ {0x3e, 0x15, 0x18},
+ {0x30, 0x07, 0x17},
+ {0x3b, 0x2c, 0x30},
+ {0x15, 0x07, 0x2c},
+ {0x17, 0x27, 0x1d},
+ {0x3f, 0x1e, 0x33},
+ {0x0d, 0x17, 0x10},
+ {0x15, 0x0e, 0x30},
+ {0x09, 0x05, 0x30},
+ {0x2d, 0x20, 0x15},
+ {0x3c, 0x3d, 0x30},
+ {0x0c, 0x17, 0x1c},
+ {0x1a, 0x0d, 0x25},
+ {0x2b, 0x2b, 0x2a},
+ {0x02, 0x16, 0x2d},
+ {0x17, 0x31, 0x17},
+ {0x00, 0x08, 0x13},
+ {0x37, 0x35, 0x21},
+ {0x1e, 0x1c, 0x1f},
+ {0x2b, 0x32, 0x1c},
+ {0x10, 0x2a, 0x16},
+ {0x3a, 0x33, 0x31},
+ {0x17, 0x2b, 0x2a},
+ {0x0c, 0x3d, 0x11},
+ {0x28, 0x0a, 0x30},
+ {0x23, 0x0a, 0x26},
+ {0x0a, 0x14, 0x24},
+ {0x0b, 0x0f, 0x30},
+ {0x1b, 0x1e, 0x29},
+ {0x02, 0x35, 0x28},
+ {0x3b, 0x02, 0x14},
+ {0x00, 0x0f, 0x35},
+ {0x1c, 0x3c, 0x2e},
+ {0x28, 0x38, 0x19},
+ {0x1b, 0x11, 0x12},
+ {0x09, 0x16, 0x10},
+ {0x2e, 0x0d, 0x20},
+ {0x3d, 0x04, 0x32},
+ {0x16, 0x2c, 0x25},
+ {0x02, 0x3d, 0x18},
+ {0x0b, 0x13, 0x1c},
+ {0x22, 0x2a, 0x1c},
+ {0x20, 0x27, 0x22},
+ {0x05, 0x26, 0x22},
+ {0x12, 0x1d, 0x2c},
+ {0x08, 0x05, 0x2e},
+ {0x3f, 0x1c, 0x17},
+ {0x24, 0x0d, 0x33},
+ {0x36, 0x08, 0x24},
+ {0x10, 0x22, 0x29},
+ {0x1c, 0x0a, 0x11},
+ {0x25, 0x0f, 0x10},
+ {0x24, 0x38, 0x2f},
+ {0x25, 0x32, 0x1e},
+ {0x06, 0x2a, 0x29},
+ {0x3e, 0x3a, 0x28},
+ {0x34, 0x17, 0x33},
+ {0x18, 0x33, 0x17},
+ {0x07, 0x14, 0x1f},
+ {0x11, 0x17, 0x20},
+ {0x13, 0x0e, 0x14},
+ {0x3b, 0x1c, 0x12},
+ {0x2a, 0x13, 0x37},
+ {0x2a, 0x35, 0x32},
+ {0x30, 0x02, 0x25},
+ {0x00, 0x07, 0x1f},
+ {0x0c, 0x04, 0x2c},
+ {0x37, 0x37, 0x30},
+ {0x25, 0x12, 0x25},
+ {0x12, 0x22, 0x21},
+ {0x22, 0x35, 0x33},
+ {0x07, 0x20, 0x2d},
+ {0x27, 0x0e, 0x30},
+ {0x34, 0x19, 0x1a},
+ {0x0a, 0x3c, 0x25},
+ {0x07, 0x1d, 0x2b},
+ {0x31, 0x3a, 0x12},
+ {0x1a, 0x3d, 0x37},
+ {0x16, 0x15, 0x16},
+ {0x39, 0x13, 0x15},
+ {0x2d, 0x03, 0x2e},
+ {0x06, 0x39, 0x2c},
+ {0x16, 0x00, 0x13},
+ {0x35, 0x2a, 0x35},
+ {0x24, 0x01, 0x18},
+ {0x24, 0x37, 0x28},
+ {0x25, 0x1b, 0x34},
+ {0x25, 0x19, 0x17},
+ {0x27, 0x2f, 0x1b},
+ {0x27, 0x0d, 0x10},
+ {0x36, 0x3c, 0x30},
+ {0x3c, 0x33, 0x23},
+ {0x3e, 0x27, 0x1e},
+ {0x25, 0x2d, 0x29},
+ {0x1f, 0x12, 0x21},
+ {0x37, 0x32, 0x1f},
+ {0x11, 0x21, 0x35},
+ {0x30, 0x0c, 0x19},
+ {0x25, 0x3d, 0x26},
+ {0x17, 0x02, 0x1d},
+ {0x14, 0x2e, 0x11},
+ {0x38, 0x13, 0x30},
+ {0x0a, 0x2b, 0x20},
+ {0x1e, 0x10, 0x15},
+ {0x37, 0x30, 0x2e},
+ {0x1e, 0x04, 0x2c},
+ {0x14, 0x34, 0x19},
+ {0x08, 0x14, 0x18},
+ {0x0e, 0x1c, 0x30},
+ {0x1a, 0x2e, 0x1b},
+ {0x1f, 0x39, 0x31},
+ {0x0c, 0x1c, 0x28},
+ {0x3e, 0x33, 0x23},
+ {0x0f, 0x13, 0x16},
+ {0x25, 0x39, 0x2f},
+ {0x14, 0x1b, 0x1a},
+ {0x28, 0x3e, 0x21},
+ {0x2d, 0x19, 0x11},
+ {0x0c, 0x34, 0x32},
+ {0x39, 0x31, 0x19},
+ {0x1a, 0x08, 0x34},
+ {0x09, 0x2f, 0x11},
+ {0x30, 0x04, 0x1c},
+ {0x02, 0x3b, 0x1b},
+ {0x33, 0x21, 0x33},
+ {0x38, 0x02, 0x1a},
+ {0x31, 0x38, 0x32},
+ {0x1f, 0x1d, 0x16},
+ {0x17, 0x10, 0x1b},
+ {0x32, 0x20, 0x17},
+ {0x00, 0x33, 0x12},
+ {0x21, 0x0f, 0x27},
+ {0x14, 0x19, 0x27},
+ {0x24, 0x2c, 0x37},
+ {0x25, 0x05, 0x2f},
+ {0x3d, 0x25, 0x11},
+ {0x12, 0x30, 0x1a},
+ {0x16, 0x03, 0x1a},
+ {0x14, 0x09, 0x13},
+ {0x02, 0x23, 0x22},
+ {0x01, 0x3c, 0x10},
+ {0x3f, 0x2d, 0x23},
+ {0x31, 0x3f, 0x23},
+ {0x17, 0x00, 0x33},
+ {0x3f, 0x0f, 0x2f},
+ {0x26, 0x07, 0x15},
+ {0x21, 0x2b, 0x2a},
+ {0x38, 0x39, 0x1e},
+ {0x09, 0x25, 0x2b},
+ {0x3b, 0x30, 0x25},
+ {0x12, 0x2d, 0x13},
+ {0x32, 0x19, 0x28},
+ {0x24, 0x1c, 0x2d},
+ {0x35, 0x32, 0x26},
+ {0x0d, 0x23, 0x1e},
+ {0x1d, 0x07, 0x21},
+ {0x0b, 0x34, 0x17},
+ {0x2d, 0x32, 0x32},
+ {0x3a, 0x3c, 0x35},
+ {0x1a, 0x10, 0x33},
+ {0x1a, 0x07, 0x22},
+ {0x3b, 0x1b, 0x2a},
+ {0x33, 0x1f, 0x26},
+ {0x0e, 0x35, 0x1a},
+ {0x3b, 0x0a, 0x1c},
+ {0x11, 0x07, 0x11},
+ {0x0d, 0x3c, 0x2d},
+ {0x1e, 0x37, 0x29},
+ {0x11, 0x05, 0x12},
+ {0x15, 0x2f, 0x1c},
+ {0x24, 0x31, 0x16},
+ {0x2b, 0x21, 0x1b},
+ {0x23, 0x10, 0x31},
+ {0x02, 0x14, 0x29},
+ {0x26, 0x20, 0x16},
+ {0x10, 0x17, 0x10},
+ {0x0b, 0x0f, 0x33},
+ {0x01, 0x2e, 0x14},
+ {0x21, 0x0e, 0x37},
+ {0x1a, 0x1d, 0x2f},
+ {0x1e, 0x30, 0x24},
+ {0x04, 0x14, 0x2d},
+ {0x11, 0x00, 0x30},
+ {0x08, 0x2a, 0x1d},
+ {0x1d, 0x22, 0x21},
+ {0x24, 0x2c, 0x37},
+ {0x24, 0x11, 0x12},
+ {0x04, 0x2e, 0x28},
+ {0x1d, 0x18, 0x23},
+ {0x3c, 0x16, 0x16},
+ {0x10, 0x17, 0x31},
+ {0x20, 0x21, 0x12},
+ {0x33, 0x3e, 0x34},
+ {0x06, 0x13, 0x13},
+ {0x17, 0x38, 0x2b},
+ {0x14, 0x0d, 0x15},
+ {0x24, 0x3b, 0x2b},
+ {0x34, 0x3b, 0x1e},
+ {0x18, 0x07, 0x34},
+ {0x37, 0x1d, 0x1f},
+ {0x0b, 0x29, 0x20},
+ {0x12, 0x1e, 0x1d},
+ {0x1a, 0x24, 0x24},
+ {0x3d, 0x28, 0x24},
+ {0x0b, 0x12, 0x33},
+ {0x1b, 0x3a, 0x22},
+ {0x14, 0x13, 0x2a},
+ {0x31, 0x38, 0x15},
+ {0x37, 0x2b, 0x2e},
+ {0x19, 0x1e, 0x2c},
+ {0x3f, 0x1b, 0x2a},
+ {0x33, 0x1f, 0x33},
+ {0x3f, 0x15, 0x29},
+ {0x01, 0x1e, 0x18},
+ {0x1f, 0x22, 0x19},
+ {0x33, 0x3c, 0x34},
+ {0x1e, 0x12, 0x22},
+ {0x0d, 0x37, 0x2c},
+ {0x0f, 0x08, 0x31},
+ {0x2e, 0x09, 0x36},
+ {0x01, 0x05, 0x1e},
+ {0x1c, 0x04, 0x1e},
+ {0x0c, 0x01, 0x1c},
+ {0x29, 0x28, 0x2f},
+ {0x39, 0x2d, 0x14},
+ {0x09, 0x22, 0x36},
+ {0x04, 0x37, 0x37},
+ {0x2d, 0x2f, 0x35},
+ {0x24, 0x23, 0x1b},
+ {0x08, 0x20, 0x32},
+ {0x20, 0x1f, 0x34},
+ {0x02, 0x31, 0x19},
+ {0x18, 0x13, 0x36},
+ {0x06, 0x2b, 0x1e},
+ {0x0e, 0x1b, 0x10},
+ {0x2f, 0x0e, 0x1c},
+ {0x11, 0x38, 0x13},
+ {0x01, 0x37, 0x19},
+ {0x14, 0x11, 0x26},
+ {0x31, 0x3d, 0x33},
+ {0x1d, 0x1b, 0x34},
+ {0x25, 0x31, 0x2f},
+ {0x11, 0x0a, 0x2f},
+ {0x39, 0x17, 0x1b},
+ {0x05, 0x0e, 0x13},
+ {0x29, 0x25, 0x22},
+ {0x15, 0x0d, 0x20},
+ {0x2b, 0x27, 0x21},
+ {0x3e, 0x24, 0x27},
+ {0x2a, 0x2b, 0x16},
+ {0x24, 0x3d, 0x15},
+ {0x15, 0x30, 0x31},
+ {0x0f, 0x33, 0x24},
+ {0x06, 0x16, 0x13},
+ {0x06, 0x31, 0x10},
+ {0x2e, 0x3f, 0x10},
+ {0x05, 0x0d, 0x2f},
+ {0x3c, 0x1f, 0x19},
+ {0x12, 0x13, 0x24},
+ {0x0f, 0x33, 0x36},
+ {0x15, 0x3b, 0x33},
+ {0x03, 0x0f, 0x2a},
+ {0x3b, 0x3c, 0x2c},
+ {0x36, 0x09, 0x29},
+ {0x11, 0x3b, 0x27},
+ {0x28, 0x2b, 0x31},
+ {0x1a, 0x0e, 0x2f},
+ {0x39, 0x2c, 0x31},
+ {0x0e, 0x3c, 0x35},
+ {0x2c, 0x24, 0x33},
+ {0x3d, 0x11, 0x2b},
+ {0x07, 0x3c, 0x37},
+ {0x14, 0x18, 0x13},
+ {0x1d, 0x3f, 0x2e},
+ {0x30, 0x12, 0x25},
+ {0x26, 0x1d, 0x11},
+ {0x07, 0x11, 0x1e},
+ {0x34, 0x01, 0x11},
+ {0x0b, 0x39, 0x21},
+ {0x29, 0x02, 0x29},
+ {0x15, 0x10, 0x1a},
+ {0x30, 0x1f, 0x35},
+ {0x3c, 0x2b, 0x2a},
+ {0x30, 0x3b, 0x36},
+ {0x20, 0x1a, 0x23},
+ {0x32, 0x24, 0x2b},
+ {0x15, 0x20, 0x1c},
+ {0x25, 0x3d, 0x36},
+ {0x2d, 0x14, 0x31},
+ {0x18, 0x23, 0x17},
+ {0x18, 0x05, 0x13},
+ {0x34, 0x30, 0x37},
+ {0x0e, 0x39, 0x23},
+ {0x1d, 0x1f, 0x17},
+ {0x01, 0x15, 0x2f},
+ {0x0b, 0x3e, 0x1b},
+ {0x0d, 0x19, 0x2e},
+ {0x31, 0x38, 0x1c},
+ {0x15, 0x34, 0x15},
+ {0x13, 0x19, 0x29},
+ {0x19, 0x14, 0x27},
+ {0x15, 0x18, 0x23},
+ {0x29, 0x0c, 0x27},
+ {0x2d, 0x0e, 0x17},
+ {0x34, 0x18, 0x10},
+ {0x3b, 0x1e, 0x29},
+ {0x34, 0x2c, 0x22},
+ {0x31, 0x08, 0x13},
+ {0x1d, 0x18, 0x1a},
+ {0x1c, 0x0b, 0x2a},
+ {0x19, 0x1e, 0x1a},
+ {0x23, 0x27, 0x17},
+ {0x3b, 0x0e, 0x37},
+ {0x19, 0x2b, 0x16},
+ {0x2f, 0x08, 0x21},
+ {0x37, 0x02, 0x20},
+ {0x0b, 0x32, 0x30},
+ {0x16, 0x05, 0x30},
+ {0x13, 0x05, 0x1a},
+ {0x07, 0x39, 0x19},
+ {0x0c, 0x3b, 0x2a},
+ {0x15, 0x05, 0x30},
+ {0x30, 0x05, 0x19},
+ {0x13, 0x00, 0x12},
+ {0x27, 0x16, 0x2a},
+ {0x0f, 0x28, 0x27},
+ {0x0c, 0x23, 0x2f},
+ {0x39, 0x28, 0x2a},
+ {0x24, 0x25, 0x1f},
+ {0x18, 0x29, 0x14},
+ {0x16, 0x05, 0x1a},
+ {0x35, 0x2f, 0x26},
+ {0x0a, 0x3a, 0x29},
+ {0x34, 0x2c, 0x36},
+ {0x2e, 0x3a, 0x15},
+ {0x1a, 0x0a, 0x2d},
+ {0x16, 0x14, 0x2e},
+ {0x35, 0x28, 0x2a},
+ {0x35, 0x0f, 0x11},
+ {0x11, 0x32, 0x19},
+ {0x20, 0x1a, 0x28},
+ {0x17, 0x1a, 0x28},
+ {0x16, 0x33, 0x25},
+ {0x13, 0x2c, 0x29},
+ {0x09, 0x16, 0x33},
+ {0x1d, 0x27, 0x26},
+ {0x15, 0x0c, 0x2f},
+ {0x22, 0x1c, 0x19},
+ {0x29, 0x33, 0x10},
+ {0x2d, 0x11, 0x1b},
+ {0x16, 0x19, 0x2e},
+ {0x0d, 0x0c, 0x28},
+ {0x37, 0x3a, 0x34},
+ {0x2a, 0x1d, 0x37},
+ {0x30, 0x0a, 0x36},
+ {0x24, 0x39, 0x1b},
+ {0x39, 0x0a, 0x32},
+ {0x11, 0x03, 0x2d},
+ {0x32, 0x1d, 0x30},
+ {0x38, 0x1e, 0x27},
+ {0x2e, 0x17, 0x18},
+ {0x16, 0x17, 0x2a},
+ {0x36, 0x3b, 0x31},
+ {0x17, 0x04, 0x19},
+ {0x3a, 0x25, 0x2d},
+ {0x00, 0x36, 0x27},
+ {0x25, 0x12, 0x33},
+ {0x06, 0x0a, 0x14},
+ {0x11, 0x05, 0x2f},
+ {0x03, 0x35, 0x2f},
+ {0x0b, 0x34, 0x29},
+ {0x00, 0x31, 0x13},
+ {0x27, 0x0f, 0x1c},
+ {0x1d, 0x06, 0x2d},
+ {0x1c, 0x30, 0x27},
+ {0x2f, 0x2a, 0x27},
+ {0x16, 0x20, 0x31},
+ {0x33, 0x2b, 0x2b},
+ {0x05, 0x30, 0x36},
+ {0x29, 0x23, 0x35},
+ {0x10, 0x16, 0x2f},
+ {0x2d, 0x20, 0x29},
+ {0x37, 0x13, 0x24},
+ {0x2d, 0x0e, 0x25},
+ {0x08, 0x0a, 0x18},
+ {0x0f, 0x03, 0x1b},
+ {0x31, 0x0c, 0x37},
+ {0x1e, 0x34, 0x31},
+ {0x1b, 0x0e, 0x25},
+ {0x1a, 0x07, 0x34},
+ {0x0d, 0x3c, 0x33},
+ {0x00, 0x3a, 0x36},
+ {0x04, 0x27, 0x12},
+ {0x23, 0x18, 0x24},
+ {0x0d, 0x0b, 0x18},
+ {0x31, 0x32, 0x37},
+ {0x00, 0x0d, 0x21},
+ {0x32, 0x10, 0x12},
+ {0x26, 0x0d, 0x19},
+ {0x29, 0x24, 0x2b},
+ {0x3d, 0x21, 0x1f},
+ {0x1e, 0x1b, 0x28},
+ {0x0d, 0x12, 0x28},
+ {0x35, 0x1e, 0x23},
+ {0x0a, 0x2e, 0x22},
+ {0x27, 0x27, 0x35},
+ {0x01, 0x0e, 0x20},
+ {0x31, 0x39, 0x29},
+ {0x3b, 0x24, 0x36},
+ {0x14, 0x10, 0x33},
+ {0x18, 0x2c, 0x26},
+ {0x04, 0x2d, 0x15},
+ {0x1a, 0x11, 0x37},
+ {0x0f, 0x0b, 0x14},
+ {0x0e, 0x2c, 0x2c},
+ {0x21, 0x17, 0x2c},
+ {0x16, 0x21, 0x35},
+ {0x3e, 0x10, 0x10},
+ {0x0a, 0x05, 0x1e},
+ {0x3b, 0x09, 0x13},
+ {0x26, 0x18, 0x1e},
+ {0x23, 0x0c, 0x1a},
+ {0x33, 0x37, 0x1f},
+ {0x09, 0x12, 0x35},
+ {0x3d, 0x0d, 0x15},
+ {0x36, 0x06, 0x24},
+ {0x33, 0x30, 0x29},
+ {0x3b, 0x0f, 0x28},
+ {0x34, 0x2a, 0x2c},
+ {0x02, 0x12, 0x35},
+ {0x09, 0x22, 0x31},
+ {0x3b, 0x31, 0x1c},
+ {0x33, 0x22, 0x27},
+ {0x3d, 0x34, 0x15},
+ {0x14, 0x22, 0x28},
+ {0x28, 0x10, 0x1e},
+ {0x21, 0x31, 0x10},
+ {0x2d, 0x16, 0x21},
+ {0x1e, 0x05, 0x33},
+ {0x0f, 0x30, 0x31},
+ {0x0e, 0x1a, 0x35},
+ {0x38, 0x2e, 0x28},
+ {0x26, 0x37, 0x1e},
+ {0x2b, 0x13, 0x33},
+ {0x1f, 0x1e, 0x37},
+ {0x0a, 0x28, 0x24},
+ {0x32, 0x1c, 0x1a},
+ {0x1f, 0x3f, 0x19},
+ {0x39, 0x39, 0x29},
+ {0x2c, 0x1b, 0x14},
+ {0x15, 0x2a, 0x17},
+ {0x32, 0x0f, 0x21},
+ {0x30, 0x21, 0x18},
+ {0x23, 0x2a, 0x27},
+ {0x3d, 0x07, 0x10},
+ {0x0b, 0x3f, 0x2f},
+ {0x31, 0x02, 0x2e},
+ {0x08, 0x39, 0x2f},
+ {0x3f, 0x20, 0x18},
+ {0x2d, 0x34, 0x11},
+ {0x2e, 0x34, 0x10},
+ {0x26, 0x12, 0x23},
+ {0x25, 0x0a, 0x37},
+ {0x34, 0x09, 0x25},
+ {0x0a, 0x3e, 0x16},
+ {0x1a, 0x17, 0x11},
+ {0x38, 0x1c, 0x20},
+ {0x11, 0x21, 0x26},
+ {0x05, 0x0f, 0x18},
+ {0x26, 0x2b, 0x32},
+ {0x0a, 0x0c, 0x16},
+ {0x03, 0x29, 0x1d},
+ {0x29, 0x3b, 0x23},
+ {0x16, 0x1b, 0x29},
+ {0x07, 0x09, 0x17},
+ {0x17, 0x2c, 0x1c},
+ {0x35, 0x33, 0x30},
+ {0x17, 0x12, 0x1e},
+ {0x3d, 0x1a, 0x2b},
+ {0x21, 0x1d, 0x10},
+ {0x0a, 0x08, 0x17},
+ {0x14, 0x3c, 0x36},
+ {0x28, 0x36, 0x36},
+ {0x3b, 0x20, 0x1b},
+ {0x13, 0x22, 0x1d},
+ {0x13, 0x3a, 0x15},
+ {0x02, 0x23, 0x2c},
+ {0x3e, 0x19, 0x14},
+ {0x39, 0x3c, 0x1a},
+ {0x10, 0x08, 0x1e},
+ {0x0a, 0x13, 0x29},
+ {0x3f, 0x38, 0x2c},
+ {0x07, 0x23, 0x1f},
+ {0x19, 0x2a, 0x24},
+ {0x14, 0x3c, 0x1f},
+ {0x0d, 0x04, 0x37},
+ {0x1a, 0x2f, 0x28},
+ {0x2a, 0x1d, 0x1e},
+ {0x11, 0x37, 0x29},
+ {0x28, 0x27, 0x12},
+ {0x0d, 0x00, 0x26},
+ {0x0a, 0x3c, 0x26},
+ {0x1f, 0x1c, 0x33},
+ {0x04, 0x3a, 0x2c},
+ {0x24, 0x3d, 0x2b},
+ {0x26, 0x31, 0x2f},
+ {0x13, 0x1c, 0x21},
+ {0x3e, 0x12, 0x23},
+ {0x36, 0x0a, 0x1a},
+ {0x2d, 0x1e, 0x19},
+ {0x05, 0x1f, 0x1b},
+ {0x1e, 0x0a, 0x1f},
+ {0x20, 0x08, 0x24},
+ {0x2c, 0x0c, 0x33},
+ {0x1d, 0x1f, 0x11},
+ {0x0e, 0x12, 0x10},
+ {0x27, 0x12, 0x19},
+ {0x2a, 0x13, 0x31},
+ {0x1c, 0x04, 0x30},
+ {0x1a, 0x38, 0x1f},
+ {0x2c, 0x35, 0x25},
+ {0x07, 0x0b, 0x33},
+ {0x2d, 0x02, 0x1a},
+ {0x2a, 0x35, 0x35},
+ {0x16, 0x2f, 0x14},
+ {0x11, 0x31, 0x33},
+ {0x2c, 0x31, 0x1e},
+ {0x3c, 0x3a, 0x27},
+ {0x3c, 0x2b, 0x12},
+ {0x27, 0x1d, 0x12},
+ {0x36, 0x2c, 0x2b},
+ {0x25, 0x3b, 0x35},
+ {0x12, 0x3d, 0x27},
+ {0x13, 0x23, 0x19},
+ {0x33, 0x2c, 0x26},
+ {0x09, 0x3c, 0x12},
+ {0x15, 0x1a, 0x23},
+ {0x21, 0x07, 0x1a},
+ {0x22, 0x25, 0x20},
+ {0x19, 0x1b, 0x2c},
+ {0x3a, 0x19, 0x35},
+ {0x05, 0x26, 0x1d},
+ {0x23, 0x22, 0x25},
+ {0x0e, 0x1e, 0x11},
+ {0x13, 0x30, 0x12},
+ {0x2c, 0x22, 0x25},
+ {0x0a, 0x1d, 0x18},
+ {0x23, 0x3e, 0x1d},
+ {0x02, 0x28, 0x25},
+ {0x21, 0x0e, 0x20},
+ {0x21, 0x22, 0x37},
+ {0x18, 0x33, 0x27},
+ {0x23, 0x23, 0x31},
+ {0x24, 0x1a, 0x1a},
+ {0x3e, 0x25, 0x24},
+ {0x24, 0x01, 0x18},
+ {0x34, 0x10, 0x22},
+ {0x07, 0x00, 0x37},
+ {0x06, 0x20, 0x20},
+ {0x3a, 0x02, 0x2b},
+ {0x07, 0x2c, 0x2c},
+ {0x09, 0x2f, 0x2a},
+ {0x01, 0x32, 0x2c},
+ {0x00, 0x35, 0x13},
+ {0x2b, 0x3c, 0x1f},
+ {0x36, 0x37, 0x1e},
+ {0x20, 0x35, 0x1d},
+ {0x0c, 0x07, 0x33},
+ {0x16, 0x08, 0x12},
+ {0x3f, 0x36, 0x11},
+ {0x0b, 0x1f, 0x2d},
+ {0x21, 0x20, 0x33},
+ {0x17, 0x1a, 0x2e},
+ {0x16, 0x01, 0x2f},
+ {0x2f, 0x1c, 0x34},
+ {0x29, 0x31, 0x2e},
+ {0x3b, 0x38, 0x31},
+ {0x0d, 0x16, 0x12},
+ {0x07, 0x29, 0x24},
+ {0x33, 0x3c, 0x34},
+ {0x3e, 0x1e, 0x18},
+ {0x30, 0x02, 0x34},
+ {0x2a, 0x34, 0x1b},
+ {0x2e, 0x23, 0x18},
+ {0x34, 0x00, 0x1f},
+ {0x20, 0x0e, 0x28},
+ {0x15, 0x33, 0x37},
+ {0x27, 0x35, 0x23},
+ {0x37, 0x3e, 0x11},
+ {0x32, 0x2e, 0x36},
+ {0x3a, 0x02, 0x2b},
+ {0x00, 0x36, 0x1d},
+ {0x13, 0x29, 0x16},
+ {0x08, 0x2b, 0x37},
+ {0x08, 0x02, 0x27},
+ {0x32, 0x2d, 0x34},
+ {0x30, 0x36, 0x29},
+ {0x2e, 0x10, 0x12},
+ {0x3c, 0x2e, 0x2a},
+ {0x04, 0x33, 0x30},
+ {0x3f, 0x01, 0x22},
+ {0x37, 0x14, 0x1d},
+ {0x27, 0x00, 0x2f},
+ {0x0c, 0x39, 0x26},
+ {0x27, 0x04, 0x21},
+ {0x19, 0x08, 0x1d},
+ {0x01, 0x04, 0x1e},
+ {0x27, 0x1b, 0x2b},
+ {0x31, 0x17, 0x1f},
+ {0x07, 0x01, 0x2d},
+ {0x2e, 0x3b, 0x1f},
+ {0x34, 0x24, 0x31},
+ {0x32, 0x2b, 0x24},
+ {0x0e, 0x07, 0x1e},
+ {0x0f, 0x33, 0x10},
+ {0x16, 0x21, 0x32},
+ {0x39, 0x02, 0x1a},
+ {0x33, 0x3d, 0x22},
+ {0x0c, 0x25, 0x1a},
+ {0x29, 0x29, 0x28},
+ {0x3a, 0x32, 0x26},
+ {0x0b, 0x13, 0x22},
+ {0x1f, 0x0f, 0x1c},
+ {0x04, 0x2c, 0x20},
+ {0x39, 0x1a, 0x1b},
+ {0x1a, 0x2a, 0x1f},
+ {0x24, 0x13, 0x1a},
+ {0x31, 0x3b, 0x33},
+ {0x39, 0x23, 0x28},
+ {0x31, 0x07, 0x31},
+ {0x1f, 0x10, 0x20},
+ {0x29, 0x17, 0x32},
+ {0x26, 0x3b, 0x2d},
+ {0x02, 0x3c, 0x1c},
+ {0x0e, 0x00, 0x20},
+ {0x14, 0x3e, 0x37},
+ {0x01, 0x0f, 0x2d},
+ {0x06, 0x12, 0x27},
+ {0x30, 0x13, 0x19},
+ {0x00, 0x33, 0x2a},
+ {0x0c, 0x07, 0x27},
+ {0x11, 0x3a, 0x1c},
+ {0x15, 0x0a, 0x13},
+ {0x1f, 0x0d, 0x2a},
+ {0x37, 0x07, 0x2a},
+ {0x34, 0x35, 0x34},
+ {0x28, 0x16, 0x27},
+ {0x06, 0x02, 0x36},
+ {0x09, 0x23, 0x30},
+ {0x14, 0x02, 0x28},
+ {0x39, 0x32, 0x34},
+ {0x24, 0x35, 0x12},
+ {0x12, 0x22, 0x26},
+ {0x09, 0x07, 0x33},
+ {0x0f, 0x3e, 0x1e},
+ {0x00, 0x3c, 0x33},
+ {0x10, 0x37, 0x14},
+ {0x3a, 0x03, 0x25},
+ {0x2d, 0x1e, 0x24},
+ {0x36, 0x36, 0x26},
+ {0x1f, 0x3c, 0x1a},
+ {0x37, 0x33, 0x25},
+ {0x23, 0x13, 0x1f},
+ {0x33, 0x0d, 0x13},
+ {0x25, 0x30, 0x1e},
+ {0x17, 0x03, 0x18},
+ {0x18, 0x18, 0x14},
+ {0x30, 0x07, 0x22},
+ {0x3e, 0x33, 0x21},
+ {0x14, 0x37, 0x16},
+ {0x16, 0x00, 0x12},
+ {0x2c, 0x12, 0x2f},
+ {0x25, 0x3f, 0x1e},
+ {0x24, 0x19, 0x16},
+ {0x16, 0x0f, 0x35},
+ {0x2d, 0x10, 0x11},
+ {0x24, 0x2a, 0x28},
+ {0x19, 0x25, 0x2e},
+ {0x0c, 0x16, 0x1f},
+ {0x38, 0x21, 0x36},
+ {0x3d, 0x1a, 0x2f},
+ {0x3b, 0x32, 0x12},
+ {0x36, 0x13, 0x29},
+ {0x0e, 0x30, 0x31},
+ {0x19, 0x07, 0x2f},
+ {0x25, 0x23, 0x28},
+ {0x20, 0x08, 0x29},
+ {0x2a, 0x00, 0x30},
+ {0x30, 0x38, 0x23},
+ {0x1e, 0x0f, 0x1f},
+ {0x3b, 0x1b, 0x30},
+ {0x3a, 0x37, 0x2f},
+ {0x39, 0x37, 0x35},
+ {0x39, 0x2d, 0x2f},
+ {0x1f, 0x2e, 0x1e},
+ {0x1a, 0x2b, 0x1e},
+ {0x14, 0x17, 0x20},
+ {0x2f, 0x03, 0x11},
+ {0x1d, 0x00, 0x30},
+ {0x17, 0x2b, 0x1d},
+ {0x35, 0x28, 0x25},
+ {0x3b, 0x0f, 0x11},
+ {0x09, 0x04, 0x2e},
+ {0x23, 0x11, 0x1e},
+ {0x13, 0x37, 0x1e},
+ {0x37, 0x37, 0x1e},
+ {0x07, 0x01, 0x32},
+ {0x14, 0x06, 0x32},
+ {0x11, 0x0c, 0x2e},
+ {0x36, 0x2e, 0x24},
+ {0x15, 0x2a, 0x1c},
+ {0x22, 0x15, 0x34},
+ {0x2c, 0x1e, 0x35},
+ {0x22, 0x27, 0x33},
+ {0x19, 0x3f, 0x2d},
+ {0x21, 0x33, 0x15},
+ {0x26, 0x1a, 0x11},
+ {0x16, 0x3e, 0x12},
+ {0x2b, 0x24, 0x15},
+ {0x3c, 0x0f, 0x2d},
+ {0x31, 0x15, 0x36},
+ {0x3f, 0x24, 0x1d},
+ {0x25, 0x01, 0x37},
+ {0x33, 0x16, 0x1a},
+ {0x1f, 0x0e, 0x10},
+ {0x2f, 0x0b, 0x12},
+ {0x2a, 0x1a, 0x25},
+ {0x17, 0x0a, 0x35},
+ {0x09, 0x28, 0x35},
+ {0x02, 0x13, 0x36},
+ {0x34, 0x2f, 0x17},
+ {0x03, 0x04, 0x31},
+ {0x3e, 0x26, 0x11},
+ {0x35, 0x33, 0x31},
+ {0x22, 0x17, 0x23},
+ {0x1d, 0x05, 0x2b},
+ {0x2e, 0x27, 0x20},
+ {0x03, 0x2b, 0x1d},
+ {0x01, 0x19, 0x1e},
+ {0x0e, 0x05, 0x18},
+ {0x16, 0x25, 0x17},
+ {0x02, 0x28, 0x18},
+ {0x19, 0x0b, 0x24},
+ {0x3e, 0x35, 0x16},
+ {0x2e, 0x29, 0x25},
+ {0x3e, 0x38, 0x1e},
+ {0x3a, 0x2f, 0x12},
+ {0x14, 0x17, 0x2d},
+ {0x11, 0x12, 0x30},
+ {0x15, 0x31, 0x18},
+ {0x08, 0x0b, 0x29},
+ {0x2d, 0x00, 0x33},
+ {0x2c, 0x06, 0x1a},
+ {0x14, 0x1c, 0x2e},
+ {0x04, 0x08, 0x12},
+ {0x1b, 0x2b, 0x2d},
+ {0x2a, 0x37, 0x33},
+ {0x10, 0x27, 0x2c},
+ {0x1d, 0x0e, 0x34},
+ {0x20, 0x02, 0x12},
+ {0x1e, 0x1a, 0x2e},
+ {0x07, 0x0b, 0x10},
+ {0x36, 0x1e, 0x33},
+ {0x2b, 0x28, 0x1b},
+ {0x31, 0x25, 0x1f},
+ {0x38, 0x3a, 0x2f},
+ {0x39, 0x30, 0x2f},
+ {0x12, 0x09, 0x14},
+ {0x0e, 0x08, 0x19},
+ {0x00, 0x0d, 0x2c},
+ {0x1b, 0x0e, 0x34},
+ {0x11, 0x25, 0x15},
+ {0x0c, 0x2d, 0x26},
+ {0x36, 0x2c, 0x16},
+ {0x31, 0x31, 0x2c},
+ {0x03, 0x1a, 0x16},
+ {0x1c, 0x32, 0x14},
+ {0x0a, 0x3e, 0x36},
+ {0x33, 0x1b, 0x27},
+ {0x1f, 0x32, 0x18},
+ {0x33, 0x26, 0x33},
+ {0x1a, 0x13, 0x1a},
+ {0x0f, 0x34, 0x1c},
+ {0x35, 0x2c, 0x2f},
+ {0x38, 0x03, 0x18},
+ {0x15, 0x0f, 0x27},
+ {0x31, 0x29, 0x20},
+ {0x28, 0x0e, 0x28},
+ {0x31, 0x2c, 0x2e},
+ {0x15, 0x19, 0x1b},
+ {0x10, 0x03, 0x2f},
+ {0x2e, 0x2a, 0x32},
+ {0x2a, 0x27, 0x1b},
+ {0x36, 0x04, 0x1e},
+ {0x3b, 0x04, 0x21},
+ {0x07, 0x2f, 0x19},
+ {0x27, 0x1d, 0x1d},
+ {0x3c, 0x3d, 0x2e},
+ {0x25, 0x08, 0x32},
+ {0x3b, 0x34, 0x2a},
+ {0x0c, 0x10, 0x13},
+ {0x25, 0x35, 0x1a},
+ {0x2f, 0x19, 0x28},
+ {0x17, 0x00, 0x2b},
+ {0x0a, 0x1c, 0x17},
+ {0x0a, 0x11, 0x1b},
+ {0x35, 0x13, 0x37},
+ {0x29, 0x1c, 0x28},
+ {0x0c, 0x31, 0x35},
+ {0x3c, 0x10, 0x1a},
+ {0x1b, 0x3a, 0x2d},
+ {0x3a, 0x1c, 0x18},
+ {0x22, 0x10, 0x2d},
+ {0x1c, 0x3c, 0x12},
+ {0x17, 0x18, 0x2a},
+ {0x0b, 0x2b, 0x2f},
+ {0x2d, 0x04, 0x2e},
+ {0x3c, 0x13, 0x23},
+ {0x01, 0x1c, 0x2e},
+ {0x14, 0x16, 0x22},
+ {0x0c, 0x24, 0x13},
+ {0x35, 0x37, 0x34},
+ {0x1b, 0x30, 0x1e},
+ {0x3a, 0x1c, 0x20},
+ {0x06, 0x06, 0x36},
+ {0x09, 0x15, 0x1a},
+ {0x1b, 0x1a, 0x27},
+ {0x0f, 0x33, 0x35},
+ {0x37, 0x06, 0x23},
+ {0x3a, 0x12, 0x1d},
+ {0x00, 0x16, 0x29},
+ {0x0e, 0x1d, 0x35},
+ {0x3f, 0x38, 0x16},
+ {0x2a, 0x3c, 0x34},
+ {0x13, 0x32, 0x10},
+ {0x17, 0x2c, 0x37},
+ {0x29, 0x2a, 0x1e},
+ {0x35, 0x2f, 0x2d},
+ {0x3c, 0x2a, 0x11},
+ {0x28, 0x13, 0x21},
+ {0x19, 0x1e, 0x34},
+ {0x0c, 0x06, 0x2d},
+ {0x09, 0x04, 0x1c},
+ {0x1d, 0x2f, 0x26},
+ {0x39, 0x07, 0x16},
+ {0x14, 0x04, 0x2d},
+ {0x3a, 0x2f, 0x2e},
+ {0x29, 0x15, 0x35},
+ {0x24, 0x02, 0x36},
+ {0x3f, 0x02, 0x1a},
+ {0x0f, 0x18, 0x24},
+ {0x16, 0x1d, 0x19},
+ {0x14, 0x16, 0x10},
+ {0x29, 0x1b, 0x13},
+ {0x15, 0x0e, 0x19},
+ {0x3a, 0x2e, 0x2b},
+ {0x08, 0x30, 0x15},
+ {0x35, 0x16, 0x30},
+ {0x2e, 0x18, 0x35},
+ {0x3b, 0x0b, 0x1c},
+ {0x3a, 0x18, 0x13},
+ {0x29, 0x13, 0x1e},
+ {0x20, 0x13, 0x27},
+ {0x04, 0x1d, 0x34},
+ {0x00, 0x38, 0x19},
+ {0x08, 0x39, 0x32},
+ {0x20, 0x10, 0x26},
+ {0x08, 0x02, 0x28},
+ {0x3f, 0x0f, 0x16},
+ {0x30, 0x1f, 0x19},
+ {0x20, 0x2d, 0x10},
+ {0x38, 0x17, 0x1c},
+ {0x18, 0x31, 0x27},
+ {0x33, 0x38, 0x30},
+ {0x16, 0x33, 0x23},
+ {0x00, 0x01, 0x36},
+ {0x0d, 0x02, 0x23},
+ {0x39, 0x04, 0x1f},
+ {0x0e, 0x30, 0x24},
+ {0x06, 0x01, 0x2c},
+ {0x34, 0x33, 0x35},
+ {0x16, 0x34, 0x2e},
+ {0x32, 0x16, 0x24},
+ {0x26, 0x39, 0x34},
+ {0x1f, 0x3c, 0x1d},
+ {0x28, 0x1d, 0x37},
+ {0x17, 0x15, 0x2b},
+ {0x27, 0x39, 0x30},
+ {0x0b, 0x1b, 0x18},
+ {0x35, 0x20, 0x2d},
+ {0x0b, 0x35, 0x1c},
+ {0x03, 0x0e, 0x21},
+ {0x06, 0x0c, 0x20},
+ {0x02, 0x18, 0x34},
+ {0x1e, 0x36, 0x2d},
+ {0x16, 0x0c, 0x19},
+ {0x25, 0x09, 0x2c},
+ {0x37, 0x05, 0x2e},
+ {0x2e, 0x2b, 0x2c},
+ {0x24, 0x1a, 0x14},
+ {0x27, 0x04, 0x10},
+ {0x32, 0x38, 0x33},
+ {0x37, 0x15, 0x35},
+ {0x11, 0x3f, 0x1d},
+ {0x23, 0x23, 0x1f},
+ {0x29, 0x3f, 0x1d},
+ {0x1a, 0x3c, 0x2b},
+ {0x1b, 0x2c, 0x2c},
+ {0x38, 0x3b, 0x36},
+ {0x04, 0x13, 0x33},
+ {0x2c, 0x14, 0x12},
+ {0x1a, 0x09, 0x1b},
+ {0x36, 0x11, 0x24},
+ {0x3a, 0x3f, 0x11},
+ {0x01, 0x0e, 0x2b},
+ {0x3b, 0x03, 0x2a},
+ {0x08, 0x0d, 0x2b},
+ {0x2b, 0x13, 0x27},
+ {0x3a, 0x3c, 0x1c},
+ {0x3a, 0x15, 0x2a},
+ {0x24, 0x00, 0x17},
+ {0x3e, 0x0a, 0x15},
+ {0x0c, 0x29, 0x2d},
+ {0x1f, 0x15, 0x30},
+ {0x35, 0x18, 0x19},
+ {0x3d, 0x37, 0x37},
+ {0x12, 0x38, 0x1b},
+ {0x3b, 0x02, 0x20},
+ {0x08, 0x21, 0x19},
+ {0x2e, 0x36, 0x1d},
+ {0x15, 0x3d, 0x24},
+ {0x22, 0x0c, 0x27},
+ {0x36, 0x3f, 0x33},
+ {0x33, 0x12, 0x11},
+ {0x1a, 0x19, 0x1f},
+ {0x2b, 0x24, 0x12},
+ {0x11, 0x2a, 0x18},
+ {0x25, 0x32, 0x2a},
+ {0x2c, 0x1a, 0x12},
+ {0x26, 0x06, 0x10},
+ {0x11, 0x29, 0x33},
+ {0x2c, 0x09, 0x14},
+ {0x2b, 0x12, 0x2b},
+ {0x1d, 0x03, 0x24},
+ {0x00, 0x12, 0x15},
+ {0x22, 0x3d, 0x26},
+ {0x15, 0x37, 0x1a},
+ {0x0f, 0x12, 0x37},
+ {0x24, 0x01, 0x18},
+ {0x2a, 0x17, 0x13},
+ {0x14, 0x3b, 0x29},
+ {0x2a, 0x19, 0x32},
+ {0x2d, 0x17, 0x17},
+ {0x0b, 0x2c, 0x33},
+ {0x07, 0x2d, 0x34},
+ {0x07, 0x38, 0x1d},
+ {0x1f, 0x36, 0x22},
+ {0x11, 0x0a, 0x17},
+ {0x14, 0x11, 0x13},
+ {0x2a, 0x17, 0x25},
+ {0x01, 0x3a, 0x1c},
+ {0x26, 0x27, 0x30},
+ {0x2d, 0x3b, 0x35},
+ {0x3a, 0x30, 0x34},
+ {0x06, 0x3a, 0x1c},
+ {0x2d, 0x05, 0x13},
+ {0x21, 0x32, 0x12},
+ {0x3e, 0x1e, 0x2c},
+ {0x3a, 0x3f, 0x2d},
+ {0x20, 0x2a, 0x34},
+ {0x26, 0x03, 0x1a},
+ {0x19, 0x27, 0x2e},
+ {0x31, 0x04, 0x26},
+ {0x2a, 0x3f, 0x30},
+ {0x25, 0x23, 0x2a},
+ {0x08, 0x08, 0x35},
+ {0x2c, 0x30, 0x1e},
+ {0x08, 0x05, 0x18},
+ {0x06, 0x09, 0x2d},
+ {0x19, 0x00, 0x27},
+ {0x0d, 0x10, 0x19},
+ {0x1c, 0x00, 0x13},
+ {0x3d, 0x0b, 0x24},
+ {0x2e, 0x1f, 0x16},
+ {0x3d, 0x18, 0x34},
+ {0x12, 0x1e, 0x15},
+ {0x15, 0x39, 0x25},
+ {0x33, 0x0f, 0x17},
+ {0x1a, 0x1c, 0x1b},
+ {0x37, 0x29, 0x1b},
+ {0x3b, 0x38, 0x12},
+ {0x1d, 0x22, 0x34},
+ {0x26, 0x0a, 0x31},
+ {0x16, 0x2d, 0x13},
+ {0x0d, 0x20, 0x27},
+ {0x24, 0x1d, 0x16},
+ {0x2e, 0x2b, 0x18},
+ {0x16, 0x2a, 0x1b},
+ {0x24, 0x17, 0x36},
+ {0x02, 0x05, 0x2b},
+ {0x37, 0x1a, 0x17},
+ {0x11, 0x3d, 0x2c},
+ {0x1e, 0x2f, 0x22},
+ {0x2c, 0x29, 0x1a},
+ {0x2f, 0x04, 0x25},
+ {0x36, 0x0c, 0x35},
+ {0x30, 0x3e, 0x12},
+ {0x11, 0x30, 0x37},
+ {0x12, 0x21, 0x2e},
+ {0x21, 0x30, 0x17},
+ {0x2c, 0x3d, 0x24},
+ {0x11, 0x23, 0x14},
+ {0x1a, 0x32, 0x17},
+ {0x39, 0x27, 0x18},
+ {0x0f, 0x24, 0x19},
+ {0x00, 0x3d, 0x37},
+ {0x2c, 0x3c, 0x1c},
+ {0x0b, 0x39, 0x23},
+ {0x0e, 0x04, 0x1f},
+ {0x1c, 0x31, 0x14},
+ {0x00, 0x04, 0x15},
+ {0x26, 0x2a, 0x2a},
+ {0x20, 0x25, 0x2a},
+ {0x0b, 0x3c, 0x33},
+ {0x11, 0x0b, 0x2e},
+ {0x37, 0x22, 0x2e},
+ {0x0e, 0x22, 0x26},
+ {0x18, 0x2d, 0x27},
+ {0x06, 0x0c, 0x1c},
+ {0x26, 0x18, 0x2f},
+ {0x3a, 0x01, 0x2a},
+ {0x2f, 0x31, 0x34},
+ {0x1f, 0x34, 0x1a},
+ {0x31, 0x05, 0x10},
+ {0x2e, 0x17, 0x34},
+ {0x18, 0x22, 0x23},
+ {0x23, 0x21, 0x32},
+ {0x07, 0x08, 0x22},
+ {0x26, 0x1c, 0x22},
+ {0x31, 0x12, 0x2f},
+ {0x08, 0x1f, 0x10},
+ {0x27, 0x15, 0x2a},
+ {0x1f, 0x0b, 0x26},
+ {0x2f, 0x14, 0x35},
+ {0x24, 0x1f, 0x26},
+ {0x3b, 0x23, 0x33},
+ {0x20, 0x3e, 0x2d},
+ {0x17, 0x0c, 0x15},
+ {0x13, 0x39, 0x1a},
+ {0x30, 0x14, 0x25},
+ {0x09, 0x07, 0x17},
+ {0x38, 0x38, 0x1f},
+ {0x29, 0x24, 0x27},
+ {0x17, 0x27, 0x28},
+ {0x1b, 0x12, 0x2a},
+ {0x2b, 0x3d, 0x2d},
+ {0x19, 0x34, 0x1c},
+ {0x01, 0x1d, 0x10},
+ {0x08, 0x39, 0x11},
+ {0x0e, 0x36, 0x1b},
+ {0x26, 0x13, 0x10},
+ {0x16, 0x28, 0x1e},
+ {0x3c, 0x28, 0x17},
+ {0x3e, 0x39, 0x34},
+ {0x0a, 0x03, 0x2e},
+ {0x37, 0x1a, 0x13},
+ {0x2b, 0x33, 0x26},
+ {0x13, 0x2c, 0x21},
+ {0x25, 0x14, 0x10},
+ {0x16, 0x0b, 0x35},
+ {0x1d, 0x35, 0x33},
+ {0x21, 0x08, 0x33},
+ {0x28, 0x21, 0x1a},
+ {0x12, 0x0c, 0x1b},
+ {0x36, 0x2a, 0x19},
+ {0x2c, 0x2b, 0x23},
+ {0x01, 0x0f, 0x26},
+ {0x17, 0x0c, 0x18},
+ {0x09, 0x0f, 0x11},
+ {0x2b, 0x24, 0x1c},
+ {0x09, 0x09, 0x15},
+ {0x36, 0x08, 0x13},
+ {0x20, 0x39, 0x21},
+ {0x00, 0x3a, 0x1f},
+ {0x2b, 0x36, 0x31},
+ {0x02, 0x37, 0x13},
+ {0x04, 0x34, 0x35},
+ {0x37, 0x3d, 0x1a},
+ {0x17, 0x3d, 0x13},
+ {0x2b, 0x36, 0x2f},
+ {0x13, 0x1e, 0x13},
+ {0x3e, 0x11, 0x33},
+ {0x27, 0x3a, 0x2d},
+ {0x1e, 0x31, 0x1a},
+ {0x03, 0x03, 0x2d},
+ {0x25, 0x37, 0x1f},
+ {0x11, 0x01, 0x22},
+ {0x1c, 0x12, 0x17},
+ {0x30, 0x3a, 0x30},
+ {0x17, 0x1d, 0x29},
+ {0x0e, 0x13, 0x27},
+ {0x1a, 0x2e, 0x24},
+ {0x2d, 0x00, 0x1c},
+ {0x17, 0x28, 0x1d},
+ {0x09, 0x1f, 0x2e},
+ {0x1a, 0x2d, 0x26},
+ {0x0a, 0x13, 0x32},
+ {0x3e, 0x00, 0x27},
+ {0x0b, 0x3b, 0x30},
+ {0x08, 0x3a, 0x2d},
+ {0x22, 0x12, 0x1e},
+ {0x34, 0x1d, 0x2b},
+ {0x26, 0x22, 0x35},
+ {0x17, 0x2c, 0x17},
+ {0x29, 0x13, 0x2d},
+ {0x2d, 0x10, 0x10},
+ {0x20, 0x31, 0x23},
+ {0x1e, 0x33, 0x18},
+ {0x33, 0x06, 0x2d},
+ {0x26, 0x14, 0x27},
+ {0x22, 0x1d, 0x2a},
+ {0x2d, 0x06, 0x18},
+ {0x07, 0x09, 0x2e},
+ {0x21, 0x15, 0x2e},
+ {0x21, 0x38, 0x23},
+ {0x35, 0x0b, 0x34},
+ {0x24, 0x0b, 0x22},
+ {0x1e, 0x01, 0x17},
+ {0x0b, 0x24, 0x11},
+ {0x17, 0x07, 0x20},
+ {0x14, 0x25, 0x32},
+ {0x1a, 0x0e, 0x2f},
+ {0x35, 0x17, 0x1f},
+ {0x0c, 0x08, 0x21},
+ {0x30, 0x35, 0x1f},
+ {0x0c, 0x0b, 0x20},
+ {0x04, 0x10, 0x11},
+ {0x35, 0x11, 0x1e},
+ {0x33, 0x3d, 0x16},
+ {0x1e, 0x2b, 0x1d},
+ {0x1a, 0x19, 0x10},
+ {0x04, 0x06, 0x22},
+ {0x03, 0x3d, 0x24},
+ {0x2a, 0x0e, 0x35},
+ {0x03, 0x3e, 0x17},
+ {0x0b, 0x18, 0x36},
+ {0x3d, 0x0d, 0x26},
+ {0x35, 0x12, 0x20},
+ {0x1f, 0x0d, 0x16},
+ {0x23, 0x32, 0x1a},
+ {0x00, 0x3d, 0x26},
+ {0x30, 0x19, 0x36},
+ {0x12, 0x0e, 0x23},
+ {0x01, 0x23, 0x28},
+ {0x3b, 0x31, 0x11},
+ {0x2d, 0x1c, 0x36},
+ {0x2a, 0x05, 0x16},
+ {0x14, 0x0e, 0x30},
+ {0x3a, 0x37, 0x19},
+ {0x1f, 0x30, 0x25},
+ {0x10, 0x26, 0x2f},
+ {0x22, 0x11, 0x1f},
+ {0x2e, 0x2b, 0x1e},
+ {0x16, 0x16, 0x21},
+ {0x32, 0x18, 0x35},
+ {0x23, 0x32, 0x1a},
+ {0x3d, 0x0d, 0x19},
+ {0x39, 0x09, 0x23},
+ {0x30, 0x2e, 0x24},
+ {0x1e, 0x0f, 0x24},
+ {0x09, 0x21, 0x31},
+ {0x05, 0x03, 0x11},
+ {0x05, 0x22, 0x2a},
+ {0x03, 0x07, 0x37},
+ {0x04, 0x08, 0x13},
+ {0x05, 0x10, 0x34},
+ {0x37, 0x14, 0x29},
+ {0x0a, 0x24, 0x32},
+ {0x34, 0x1e, 0x1b},
+ {0x12, 0x17, 0x2e},
+ {0x01, 0x02, 0x13},
+ {0x0a, 0x0c, 0x11},
+ {0x02, 0x14, 0x13},
+ {0x0d, 0x25, 0x23},
+ {0x00, 0x07, 0x1a},
+ {0x1c, 0x28, 0x35},
+ {0x08, 0x0e, 0x2c},
+ {0x1b, 0x3c, 0x15},
+ {0x1c, 0x19, 0x1d},
+ {0x32, 0x13, 0x1a},
+ {0x1c, 0x00, 0x37},
+ {0x22, 0x1b, 0x35},
+ {0x39, 0x3e, 0x14},
+ {0x32, 0x06, 0x31},
+ {0x17, 0x05, 0x2b},
+ {0x01, 0x0f, 0x20},
+ {0x1e, 0x0f, 0x34},
+ {0x18, 0x03, 0x1f},
+ {0x2b, 0x00, 0x14},
+ {0x15, 0x3a, 0x30},
+ {0x25, 0x30, 0x21},
+ {0x0b, 0x00, 0x37},
+ {0x24, 0x37, 0x1d},
+ {0x29, 0x21, 0x16},
+ {0x24, 0x0f, 0x2c},
+ {0x3e, 0x15, 0x36},
+ {0x3c, 0x2d, 0x23},
+ {0x3d, 0x3c, 0x17},
+ {0x1a, 0x1c, 0x13},
+ {0x0a, 0x29, 0x22},
+ {0x25, 0x3f, 0x26},
+ {0x3b, 0x39, 0x2f},
+ {0x1d, 0x08, 0x16},
+ {0x0b, 0x19, 0x14},
+ {0x12, 0x01, 0x2c},
+ {0x35, 0x11, 0x2a},
+ {0x02, 0x00, 0x13},
+ {0x39, 0x2a, 0x35},
+ {0x07, 0x1a, 0x11},
+ {0x24, 0x0e, 0x1e},
+ {0x0e, 0x2c, 0x15},
+ {0x08, 0x31, 0x1b},
+ {0x21, 0x1d, 0x26},
+ {0x1d, 0x1c, 0x2a},
+ {0x1d, 0x24, 0x13},
+ {0x01, 0x00, 0x18},
+ {0x28, 0x2a, 0x37},
+ {0x15, 0x0f, 0x13},
+ {0x10, 0x32, 0x36},
+ {0x22, 0x13, 0x31},
+ {0x13, 0x05, 0x1e},
+ {0x17, 0x35, 0x35},
+ {0x3b, 0x0e, 0x24},
+ {0x35, 0x3a, 0x1d},
+ {0x1b, 0x36, 0x1b},
+ {0x03, 0x1d, 0x24},
+ {0x0f, 0x16, 0x30},
+ {0x2d, 0x09, 0x25},
+ {0x05, 0x21, 0x13},
+ {0x0a, 0x27, 0x36},
+ {0x04, 0x0d, 0x1c},
+ {0x06, 0x3e, 0x21},
+ {0x2a, 0x27, 0x33},
+ {0x28, 0x0e, 0x15},
+ {0x0b, 0x17, 0x1d},
+ {0x1d, 0x32, 0x2d},
+ {0x08, 0x3d, 0x29},
+ {0x21, 0x32, 0x17},
+ {0x33, 0x31, 0x22},
+ {0x0e, 0x03, 0x21},
+ {0x0d, 0x0b, 0x16},
+ {0x3e, 0x2a, 0x2e},
+ {0x19, 0x36, 0x2a},
+ {0x0d, 0x00, 0x14},
+ {0x22, 0x07, 0x36},
+ {0x0a, 0x09, 0x15},
+ {0x14, 0x10, 0x22},
+ {0x07, 0x16, 0x2c},
+ {0x36, 0x13, 0x15},
+ {0x09, 0x2f, 0x1b},
+ {0x20, 0x3b, 0x2e},
+ {0x3a, 0x3a, 0x16},
+ {0x0d, 0x15, 0x2a},
+ {0x39, 0x13, 0x2b},
+ {0x0b, 0x01, 0x2a},
+ {0x13, 0x17, 0x1e},
+ {0x08, 0x17, 0x1e},
+ {0x0c, 0x0f, 0x34},
+ {0x1f, 0x31, 0x12},
+ {0x07, 0x3a, 0x1d},
+ {0x35, 0x1e, 0x12},
+ {0x24, 0x2c, 0x15},
+ {0x0e, 0x21, 0x19},
+ {0x34, 0x3b, 0x33},
+ {0x19, 0x0f, 0x28},
+ {0x10, 0x2f, 0x2e},
+ {0x23, 0x27, 0x31},
+ {0x39, 0x2e, 0x18},
+ {0x3c, 0x3f, 0x24},
+ {0x07, 0x23, 0x30},
+ {0x28, 0x13, 0x35},
+ {0x13, 0x0a, 0x10},
+ {0x35, 0x19, 0x33},
+ {0x23, 0x28, 0x29},
+ {0x13, 0x2f, 0x1a},
+ {0x3a, 0x19, 0x14},
+ {0x37, 0x36, 0x26},
+ {0x20, 0x3b, 0x15},
+ {0x37, 0x39, 0x10},
+ {0x3c, 0x21, 0x34},
+ {0x1c, 0x38, 0x30},
+ {0x15, 0x07, 0x26},
+ {0x27, 0x21, 0x19},
+ {0x18, 0x11, 0x23},
+ {0x30, 0x28, 0x37},
+ {0x32, 0x2d, 0x1f},
+ {0x2c, 0x3f, 0x30},
+ {0x1d, 0x2f, 0x26},
+ {0x01, 0x11, 0x1c},
+ {0x3b, 0x0f, 0x12},
+ {0x2a, 0x17, 0x27},
+ {0x05, 0x00, 0x1b},
+ {0x25, 0x1c, 0x32},
+ {0x04, 0x22, 0x2d},
+ {0x10, 0x0f, 0x25},
+ {0x0d, 0x39, 0x30},
+ {0x0b, 0x2e, 0x27},
+ {0x2d, 0x34, 0x15},
+ {0x3e, 0x30, 0x36},
+ {0x16, 0x26, 0x2a},
+ {0x05, 0x3f, 0x2b},
+ {0x20, 0x3b, 0x2e},
+ {0x3b, 0x1c, 0x2f},
+ {0x01, 0x18, 0x16},
+ {0x16, 0x3d, 0x10},
+ {0x0a, 0x1f, 0x18},
+ {0x17, 0x0f, 0x22},
+ {0x06, 0x13, 0x11},
+ {0x38, 0x21, 0x17},
+ {0x17, 0x0a, 0x37},
+ {0x1c, 0x19, 0x30},
+ {0x16, 0x38, 0x31},
+ {0x30, 0x10, 0x36},
+ {0x31, 0x2f, 0x26},
+ {0x3c, 0x1b, 0x23},
+ {0x33, 0x2f, 0x19},
+ {0x16, 0x35, 0x25},
+ {0x3a, 0x18, 0x1f},
+ {0x37, 0x01, 0x1e},
+ {0x0d, 0x18, 0x12},
+ {0x1f, 0x1c, 0x1b},
+ {0x07, 0x34, 0x2d},
+ {0x0b, 0x3f, 0x33},
+ {0x1e, 0x34, 0x1d},
+ {0x2c, 0x13, 0x2c},
+ {0x20, 0x20, 0x13},
+ {0x20, 0x0f, 0x31},
+ {0x08, 0x0f, 0x24},
+ {0x18, 0x3d, 0x1c},
+ {0x36, 0x34, 0x27},
+ {0x33, 0x2a, 0x25},
+ {0x2d, 0x30, 0x26},
+ {0x3d, 0x37, 0x26},
+ {0x25, 0x11, 0x11},
+ {0x03, 0x05, 0x18},
+ {0x10, 0x04, 0x29},
+ {0x07, 0x2e, 0x36},
+ {0x2a, 0x29, 0x15},
+ {0x3a, 0x0e, 0x33},
+ {0x2a, 0x06, 0x29},
+ {0x3d, 0x01, 0x29},
+ {0x27, 0x0e, 0x16},
+ {0x1d, 0x28, 0x1b},
+ {0x10, 0x33, 0x2b},
+ {0x0c, 0x14, 0x1d},
+ {0x15, 0x3f, 0x25},
+ {0x37, 0x23, 0x1e},
+ {0x04, 0x2c, 0x1c},
+ {0x15, 0x34, 0x2a},
+ {0x09, 0x2f, 0x15},
+ {0x02, 0x3f, 0x14},
+ {0x19, 0x2c, 0x33},
+ {0x39, 0x32, 0x20},
+ {0x2a, 0x18, 0x32},
+ {0x17, 0x23, 0x21},
+ {0x0b, 0x2d, 0x25},
+ {0x24, 0x3a, 0x2d},
+ {0x31, 0x3f, 0x34},
+ {0x18, 0x19, 0x24},
+ {0x1e, 0x15, 0x1a},
+ {0x17, 0x33, 0x2b},
+ {0x23, 0x09, 0x26},
+ {0x1b, 0x0d, 0x15},
+ {0x36, 0x26, 0x28},
+ {0x3a, 0x1c, 0x14},
+ {0x0c, 0x3e, 0x10},
+ {0x18, 0x06, 0x35},
+ {0x37, 0x26, 0x36},
+ {0x21, 0x26, 0x17},
+ {0x3d, 0x1c, 0x2c},
+ {0x16, 0x25, 0x1d},
+ {0x1e, 0x0b, 0x1e},
+ {0x1d, 0x0d, 0x32},
+ {0x08, 0x1f, 0x1b},
+ {0x12, 0x1c, 0x12},
+ {0x20, 0x2a, 0x28},
+ {0x06, 0x3b, 0x35},
+ {0x39, 0x0e, 0x1e},
+ {0x31, 0x30, 0x28},
+ {0x02, 0x21, 0x14},
+ {0x06, 0x1e, 0x29},
+ {0x16, 0x09, 0x1c},
+ {0x27, 0x32, 0x2d},
+ {0x39, 0x03, 0x27},
+ {0x29, 0x09, 0x1e},
+ {0x1b, 0x11, 0x1c},
+ {0x28, 0x3a, 0x2c},
+ {0x03, 0x03, 0x18},
+ {0x23, 0x09, 0x2f},
+ {0x30, 0x17, 0x23},
+ {0x0f, 0x25, 0x33},
+ {0x06, 0x24, 0x37},
+ {0x22, 0x09, 0x33},
+ {0x2c, 0x09, 0x2a},
+ {0x0c, 0x12, 0x2a},
+ {0x28, 0x20, 0x10},
+ {0x15, 0x29, 0x33},
+ {0x0f, 0x1a, 0x13},
+ {0x13, 0x18, 0x36},
+ {0x2e, 0x16, 0x13},
+ {0x3c, 0x1a, 0x15},
+ {0x3a, 0x11, 0x32},
+ {0x02, 0x0a, 0x2c},
+ {0x19, 0x39, 0x11},
+ {0x31, 0x3e, 0x1d},
+ {0x32, 0x14, 0x32},
+ {0x12, 0x2e, 0x34},
+ {0x3e, 0x36, 0x23},
+ {0x37, 0x3e, 0x15},
+ {0x15, 0x35, 0x34},
+ {0x01, 0x3a, 0x2c},
+ {0x26, 0x25, 0x22},
+ {0x01, 0x2b, 0x37},
+ {0x1c, 0x3d, 0x33},
+ {0x3e, 0x10, 0x1c},
+ {0x26, 0x33, 0x19},
+ {0x05, 0x19, 0x17},
+ {0x12, 0x38, 0x1c},
+ {0x15, 0x3c, 0x32},
+ {0x3f, 0x0f, 0x37},
+ {0x02, 0x39, 0x32},
+ {0x13, 0x00, 0x1d},
+ {0x1d, 0x2c, 0x10},
+ {0x39, 0x13, 0x31},
+ {0x0f, 0x37, 0x19},
+ {0x09, 0x0d, 0x2a},
+ {0x20, 0x2f, 0x32},
+ {0x3b, 0x34, 0x22},
+ {0x26, 0x14, 0x10},
+ {0x24, 0x3d, 0x22},
+ {0x0b, 0x31, 0x23},
+ {0x2f, 0x2d, 0x2a},
+ {0x30, 0x04, 0x35},
+ {0x19, 0x20, 0x2a},
+ {0x16, 0x36, 0x37},
+ {0x14, 0x28, 0x37},
+ {0x11, 0x0b, 0x27},
+ {0x1d, 0x06, 0x29},
+ {0x35, 0x16, 0x2e},
+ {0x24, 0x2e, 0x29},
+ {0x36, 0x14, 0x2a},
+ {0x21, 0x0c, 0x1f},
+ {0x3f, 0x39, 0x19},
+ {0x27, 0x10, 0x2a},
+ {0x1e, 0x12, 0x34},
+ {0x10, 0x24, 0x34},
+ {0x1d, 0x13, 0x1d},
+ {0x17, 0x16, 0x37},
+ {0x27, 0x1b, 0x27},
+ {0x07, 0x24, 0x21},
+ {0x37, 0x21, 0x11},
+ {0x37, 0x28, 0x24},
+ {0x19, 0x02, 0x1c},
+ {0x14, 0x12, 0x1d},
+ {0x1b, 0x24, 0x2e},
+ {0x2e, 0x3a, 0x15},
+ {0x37, 0x34, 0x21},
+ {0x33, 0x2d, 0x29},
+ {0x2f, 0x1e, 0x34},
+ {0x29, 0x3c, 0x12},
+ {0x05, 0x15, 0x20},
+ {0x05, 0x3e, 0x19},
+ {0x18, 0x0b, 0x30},
+ {0x2f, 0x02, 0x27},
+ {0x14, 0x1c, 0x34},
+ {0x12, 0x20, 0x30},
+ {0x2b, 0x22, 0x1b},
+ {0x06, 0x31, 0x28},
+ {0x15, 0x2d, 0x12},
+ {0x01, 0x0e, 0x13},
+ {0x13, 0x0c, 0x28},
+ {0x07, 0x2a, 0x14},
+ {0x1d, 0x36, 0x14},
+ {0x15, 0x2b, 0x26},
+ {0x03, 0x25, 0x15},
+ {0x3e, 0x3b, 0x20},
+ {0x35, 0x0c, 0x25},
+ {0x2b, 0x16, 0x35},
+ {0x1e, 0x31, 0x2c},
+ {0x06, 0x03, 0x29},
+ {0x24, 0x07, 0x1f},
+ {0x32, 0x2f, 0x19},
+ {0x25, 0x21, 0x31},
+ {0x22, 0x26, 0x1d},
+ {0x00, 0x1b, 0x18},
+ {0x2a, 0x24, 0x31},
+ {0x20, 0x06, 0x2f},
+ {0x1e, 0x32, 0x26},
+ {0x32, 0x39, 0x12},
+ {0x20, 0x01, 0x19},
+ {0x0f, 0x15, 0x15},
+ {0x27, 0x10, 0x2e},
+ {0x09, 0x25, 0x19},
+ {0x29, 0x37, 0x30},
+ {0x13, 0x1c, 0x1d},
+ {0x29, 0x2d, 0x26},
+ {0x02, 0x1a, 0x16},
+ {0x1d, 0x2b, 0x1c},
+ {0x18, 0x04, 0x34},
+ {0x28, 0x2a, 0x21},
+ {0x15, 0x1b, 0x2e},
+ {0x16, 0x01, 0x10},
+ {0x05, 0x09, 0x14},
+ {0x22, 0x03, 0x22},
+ {0x02, 0x1b, 0x34},
+ {0x29, 0x2a, 0x23},
+ {0x26, 0x36, 0x13},
+ {0x23, 0x3d, 0x1a},
+ {0x1d, 0x10, 0x24},
+ {0x25, 0x2b, 0x37},
+ {0x19, 0x24, 0x26},
+ {0x28, 0x13, 0x16},
+ {0x17, 0x14, 0x19},
+ {0x0b, 0x2f, 0x25},
+ {0x37, 0x34, 0x37},
+ {0x39, 0x21, 0x1b},
+ {0x0f, 0x3d, 0x2d},
+ {0x0d, 0x10, 0x20},
+ {0x05, 0x0b, 0x2d},
+ {0x01, 0x12, 0x24},
+ {0x18, 0x3d, 0x32},
+ {0x09, 0x21, 0x26},
+ {0x1a, 0x0e, 0x1f},
+ {0x30, 0x06, 0x1f},
+ {0x0b, 0x3c, 0x29},
+ {0x07, 0x3e, 0x27},
+ {0x13, 0x1e, 0x1a},
+ {0x13, 0x07, 0x23},
+ {0x10, 0x34, 0x1e},
+ {0x32, 0x17, 0x23},
+ {0x35, 0x16, 0x31},
+ {0x32, 0x2e, 0x1b},
+ {0x28, 0x0e, 0x22},
+ {0x14, 0x3a, 0x23},
+ {0x22, 0x03, 0x29},
+ {0x2a, 0x10, 0x20},
+ {0x3e, 0x3c, 0x27},
+ {0x16, 0x20, 0x12},
+ {0x3f, 0x24, 0x31},
+ {0x0d, 0x2e, 0x32},
+ {0x2f, 0x17, 0x2d},
+ {0x36, 0x3b, 0x17},
+ {0x24, 0x23, 0x18},
+ {0x37, 0x1d, 0x13},
+ {0x17, 0x3a, 0x1a},
+ {0x0a, 0x3d, 0x1e},
+ {0x05, 0x12, 0x16},
+ {0x33, 0x32, 0x25},
+ {0x1d, 0x1f, 0x29},
+ {0x34, 0x2c, 0x26},
+ {0x20, 0x29, 0x35},
+ {0x0e, 0x32, 0x17},
+ {0x01, 0x39, 0x2d},
+ {0x27, 0x24, 0x23},
+ {0x28, 0x3f, 0x18},
+ {0x39, 0x38, 0x25},
+ {0x23, 0x11, 0x11},
+ {0x19, 0x2c, 0x29},
+ {0x30, 0x08, 0x28},
+ {0x25, 0x27, 0x1d},
+ {0x17, 0x25, 0x21},
+ {0x09, 0x3d, 0x16},
+ {0x1b, 0x0f, 0x2c},
+ {0x1b, 0x12, 0x22},
+ {0x28, 0x3e, 0x26},
+ {0x34, 0x10, 0x1b},
+ {0x02, 0x34, 0x15},
+ {0x1a, 0x29, 0x19},
+ {0x29, 0x11, 0x31},
+ {0x12, 0x27, 0x17},
+ {0x27, 0x27, 0x2f},
+ {0x34, 0x27, 0x24},
+ {0x03, 0x19, 0x36},
+ {0x17, 0x1d, 0x33},
+ {0x19, 0x25, 0x1a},
+ {0x2b, 0x39, 0x13},
+ {0x3b, 0x33, 0x1d},
+ {0x27, 0x31, 0x34},
+ {0x28, 0x33, 0x37},
+ {0x09, 0x30, 0x1b},
+ {0x03, 0x3a, 0x27},
+ {0x19, 0x11, 0x1f},
+ {0x0b, 0x1a, 0x34},
+ {0x3d, 0x2a, 0x15},
+ {0x04, 0x24, 0x36},
+ {0x30, 0x23, 0x30},
+ {0x0f, 0x22, 0x1b},
+ {0x3d, 0x3d, 0x24},
+ {0x29, 0x1d, 0x12},
+ {0x16, 0x19, 0x2e},
+ {0x03, 0x12, 0x17},
+ {0x18, 0x25, 0x33},
+ {0x2f, 0x23, 0x1a},
+ {0x1a, 0x35, 0x27},
+ {0x21, 0x26, 0x19},
+ {0x1b, 0x30, 0x18},
+ {0x2b, 0x22, 0x2d},
+ {0x2c, 0x1a, 0x34},
+ {0x3e, 0x12, 0x19},
+ {0x28, 0x27, 0x15},
+ {0x1b, 0x11, 0x12},
+ {0x17, 0x15, 0x10},
+ {0x34, 0x37, 0x25},
+ {0x12, 0x3f, 0x15},
+ {0x31, 0x0d, 0x37},
+ {0x3e, 0x2a, 0x2d},
+ {0x0f, 0x24, 0x24},
+ {0x3c, 0x3f, 0x1f},
+ {0x1d, 0x34, 0x17},
+ {0x1a, 0x23, 0x1f},
+ {0x37, 0x0f, 0x10},
+ {0x32, 0x34, 0x35},
+ {0x19, 0x05, 0x22},
+ {0x33, 0x16, 0x34},
+ {0x1e, 0x14, 0x1e},
+ {0x08, 0x13, 0x29},
+ {0x3a, 0x37, 0x30},
+ {0x1d, 0x36, 0x15},
+ {0x29, 0x2e, 0x1d},
+ {0x32, 0x2e, 0x23},
+ {0x35, 0x17, 0x1c},
+ {0x36, 0x1d, 0x13},
+ {0x23, 0x34, 0x34},
+ {0x24, 0x1a, 0x37},
+ {0x2f, 0x26, 0x2e},
+ {0x1e, 0x17, 0x1a},
+ {0x1f, 0x15, 0x1f},
+ {0x2b, 0x1f, 0x19},
+ {0x0a, 0x33, 0x1a},
+ {0x35, 0x31, 0x24},
+ {0x2d, 0x17, 0x2c},
+ {0x0c, 0x21, 0x36},
+ {0x2c, 0x35, 0x35},
+ {0x1b, 0x03, 0x27},
+ {0x01, 0x0d, 0x1d},
+ {0x1c, 0x0e, 0x11},
+ {0x11, 0x2b, 0x10},
+ {0x25, 0x3b, 0x20},
+ {0x1f, 0x17, 0x19},
+ {0x20, 0x08, 0x36},
+ {0x13, 0x38, 0x19},
+ {0x1b, 0x2b, 0x24},
+ {0x0b, 0x1f, 0x29},
+ {0x27, 0x15, 0x2c},
+ {0x37, 0x39, 0x10},
+ {0x3a, 0x15, 0x2e},
+ {0x2f, 0x11, 0x36},
+ {0x24, 0x04, 0x20},
+ {0x3b, 0x2a, 0x35},
+ {0x27, 0x35, 0x34},
+ {0x0d, 0x1b, 0x20},
+ {0x10, 0x22, 0x37},
+ {0x1f, 0x38, 0x27},
+ {0x31, 0x0f, 0x28},
+ {0x28, 0x25, 0x15},
+ {0x00, 0x1d, 0x25},
+ {0x31, 0x28, 0x28},
+ {0x0b, 0x3a, 0x1d},
+ {0x2d, 0x13, 0x1b},
+ {0x03, 0x37, 0x2e},
+ {0x1d, 0x28, 0x19},
+ {0x08, 0x2d, 0x22},
+ {0x27, 0x39, 0x32},
+ {0x3f, 0x2f, 0x1d},
+ {0x33, 0x34, 0x28},
+ {0x18, 0x08, 0x31},
+ {0x23, 0x1f, 0x13},
+ {0x0d, 0x2c, 0x23},
+ {0x3a, 0x2d, 0x1a},
+ {0x02, 0x25, 0x13},
+ {0x20, 0x36, 0x34},
+ {0x12, 0x2b, 0x2d},
+ {0x35, 0x35, 0x34},
+ {0x23, 0x20, 0x21},
+ {0x3a, 0x19, 0x1b},
+ {0x1f, 0x2b, 0x19},
+ {0x35, 0x0e, 0x19},
+ {0x26, 0x24, 0x37},
+ {0x18, 0x08, 0x10},
+ {0x0c, 0x16, 0x2d},
+ {0x1f, 0x34, 0x21},
+ {0x05, 0x38, 0x19},
+ {0x14, 0x21, 0x24},
+ {0x11, 0x31, 0x14},
+ {0x3e, 0x38, 0x29},
+ {0x3f, 0x08, 0x25},
+ {0x2a, 0x1f, 0x25},
+ {0x25, 0x06, 0x28},
+ {0x0b, 0x1e, 0x14},
+ {0x1a, 0x38, 0x22},
+ {0x24, 0x18, 0x29},
+ {0x1a, 0x11, 0x20},
+ {0x3b, 0x3a, 0x1e},
+ {0x1c, 0x26, 0x1a},
+ {0x05, 0x32, 0x19},
+ {0x39, 0x2a, 0x31},
+ {0x09, 0x07, 0x25},
+ {0x05, 0x3e, 0x16},
+ {0x34, 0x26, 0x14},
+ {0x1b, 0x32, 0x26},
+ {0x05, 0x08, 0x37},
+ {0x0f, 0x03, 0x20},
+ {0x2a, 0x39, 0x31},
+ {0x08, 0x01, 0x1e},
+ {0x1d, 0x23, 0x31},
+ {0x28, 0x1b, 0x28},
+ {0x1e, 0x37, 0x14},
+ {0x13, 0x0e, 0x28},
+ {0x2a, 0x3b, 0x37},
+ {0x2f, 0x1c, 0x28},
+ {0x30, 0x30, 0x1a},
+ {0x36, 0x1f, 0x16},
+ {0x3e, 0x0d, 0x15},
+ {0x2e, 0x16, 0x18},
+ {0x15, 0x37, 0x20},
+ {0x2a, 0x33, 0x30},
+ {0x2b, 0x0e, 0x25},
+ {0x18, 0x20, 0x16},
+ {0x02, 0x19, 0x25},
+ {0x0a, 0x2e, 0x30},
+ {0x16, 0x03, 0x11},
+ {0x04, 0x27, 0x25},
+ {0x1b, 0x1c, 0x21},
+ {0x29, 0x04, 0x27},
+ {0x3d, 0x20, 0x1e},
+ {0x28, 0x33, 0x31},
+ {0x1e, 0x39, 0x10},
+ {0x31, 0x29, 0x1e},
+ {0x06, 0x25, 0x28},
+ {0x19, 0x3b, 0x12},
+ {0x0b, 0x1b, 0x1c},
+ {0x3e, 0x37, 0x20},
+ {0x0a, 0x37, 0x33},
+ {0x02, 0x2c, 0x25},
+ {0x15, 0x18, 0x14},
+ {0x3b, 0x20, 0x1c},
+ {0x22, 0x3b, 0x1c},
+ {0x24, 0x34, 0x35},
+ {0x0f, 0x2f, 0x31},
+ {0x3b, 0x17, 0x35},
+ {0x30, 0x39, 0x37},
+ {0x0d, 0x15, 0x11},
+ {0x10, 0x03, 0x1e},
+ {0x1a, 0x39, 0x33},
+ {0x2f, 0x2e, 0x28},
+ {0x1c, 0x28, 0x36},
+ {0x28, 0x18, 0x1f},
+ {0x15, 0x01, 0x30},
+ {0x3e, 0x32, 0x28},
+ {0x34, 0x2f, 0x23},
+ {0x07, 0x0c, 0x36},
+ {0x28, 0x2c, 0x34},
+ {0x2a, 0x0c, 0x1f},
+ {0x3f, 0x20, 0x13},
+ {0x2b, 0x17, 0x27},
+ {0x28, 0x29, 0x2a},
+ {0x3c, 0x13, 0x36},
+ {0x26, 0x2d, 0x2a},
+ {0x0a, 0x06, 0x1e},
+ {0x20, 0x04, 0x1a},
+ {0x02, 0x07, 0x35},
+ {0x0e, 0x18, 0x30},
+ {0x00, 0x34, 0x34},
+ {0x2f, 0x14, 0x37},
+ {0x21, 0x30, 0x1f},
+ {0x15, 0x37, 0x1b},
+ {0x3a, 0x0b, 0x32},
+ {0x22, 0x22, 0x21},
+ {0x1b, 0x35, 0x23},
+ {0x0d, 0x03, 0x1c},
+ {0x23, 0x3b, 0x13},
+ {0x0e, 0x1d, 0x1f},
+ {0x1d, 0x3f, 0x2e},
+ {0x39, 0x27, 0x2e},
+ {0x0f, 0x38, 0x20},
+ {0x31, 0x3c, 0x35},
+ {0x0b, 0x0f, 0x2e},
+ {0x06, 0x06, 0x28},
+ {0x25, 0x39, 0x23},
+ {0x0a, 0x32, 0x15},
+ {0x0f, 0x1d, 0x25},
+ {0x0c, 0x0d, 0x34},
+ {0x12, 0x2e, 0x21},
+ {0x36, 0x18, 0x1f},
+ {0x1f, 0x34, 0x1b},
+ {0x05, 0x3a, 0x36},
+ {0x2b, 0x01, 0x17},
+ {0x0e, 0x16, 0x2b},
+ {0x0e, 0x0b, 0x26},
+ {0x0d, 0x2d, 0x10},
+ {0x21, 0x11, 0x27},
+ {0x3d, 0x13, 0x32},
+ {0x15, 0x25, 0x2a},
+ {0x1b, 0x2d, 0x35},
+ {0x2c, 0x2b, 0x26},
+ {0x26, 0x1f, 0x20},
+ {0x22, 0x2b, 0x12},
+ {0x3f, 0x3d, 0x27},
+ {0x30, 0x0a, 0x36},
+ {0x35, 0x1f, 0x17},
+ {0x21, 0x08, 0x29},
+ {0x1d, 0x20, 0x33},
+ {0x34, 0x11, 0x16},
+ {0x05, 0x38, 0x2d}
+};
+
+void ApplyImageProcessingEffects(struct ImageProcessingContext *context)
+{
+ gCanvasPixels = context->canvasPixels;
+ gCanvasMonPersonality = context->personality;
+ gCanvasColumnStart = context->columnStart;
+ gCanvasRowStart = context->rowStart;
+ gCanvasColumnEnd = context->columnEnd;
+ gCanvasRowEnd = context->rowEnd;
+ gCanvasWidth = context->canvasWidth;
+ gCanvasHeight = context->canvasHeight;
+
+ switch (context->effect)
+ {
+ case IMAGE_EFFECT_POINTILLISM:
+ ApplyImageEffect_Pointillism();
+ break;
+ case IMAGE_EFFECT_BLUR:
+ ApplyImageEffect_Blur();
+ break;
+ case IMAGE_EFFECT_OUTLINE_COLORED:
+ ApplyImageEffect_BlackOutline();
+ ApplyImageEffect_PersonalityColor(gCanvasMonPersonality);
+ break;
+ case IMAGE_EFFECT_INVERT_BLACK_WHITE:
+ ApplyImageEffect_BlackOutline();
+ ApplyImageEffect_Invert();
+ ApplyImageEffect_BlackAndWhite();
+ case IMAGE_EFFECT_INVERT:
+ ApplyImageEffect_Invert();
+ break;
+ case IMAGE_EFFECT_THICK_BLACK_WHITE:
+ ApplyImageEffect_BlackOutline();
+ ApplyImageEffect_BlurRight();
+ ApplyImageEffect_BlurRight();
+ ApplyImageEffect_BlurDown();
+ ApplyImageEffect_BlackAndWhite();
+ break;
+ case IMAGE_EFFECT_SHIMMER:
+ ApplyImageEffect_Shimmer();
+ break;
+ case IMAGE_EFFECT_OUTLINE:
+ ApplyImageEffect_BlackOutline();
+ break;
+ case IMAGE_EFFECT_BLUR_RIGHT:
+ ApplyImageEffect_BlurRight();
+ break;
+ case IMAGE_EFFECT_BLUR_DOWN:
+ ApplyImageEffect_BlurDown();
+ break;
+ case IMAGE_EFFECT_GRAYSCALE_LIGHT:
+ ApplyImageEffect_Grayscale();
+ ApplyImageEffect_RedChannelGrayscale(3);
+ break;
+ case IMAGE_EFFECT_CHARCOAL:
+ ApplyImageEffect_BlackOutline();
+ ApplyImageEffect_BlurRight();
+ ApplyImageEffect_BlurDown();
+ ApplyImageEffect_BlackAndWhite();
+ ApplyImageEffect_Blur();
+ ApplyImageEffect_Blur();
+ ApplyImageEffect_RedChannelGrayscale(2);
+ ApplyImageEffect_RedChannelGrayscaleHighlight(4);
+ break;
+ }
+}
+
+static void ApplyImageEffect_RedChannelGrayscale(u8 delta)
+{
+ u8 i, j;
+
+ for (j = 0; j < gCanvasRowEnd; j++)
+ {
+ u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth];
+ u16 *pixel = &pixelRow[gCanvasColumnStart];
+ for (i = 0; i < gCanvasColumnEnd; i++, pixel++)
+ {
+ if (!(0x8000 & *pixel))
+ {
+ // Gets the grayscale value, based on the pixel's red channel.
+ // Also adds a delta to skew lighter or darker.
+ u8 grayValue = (31 & *pixel);
+ grayValue += delta;
+ if (grayValue > 31)
+ grayValue = 31;
+
+ *pixel = RGB2(grayValue, grayValue, grayValue);
+ }
+ }
+ }
+}
+
+static void ApplyImageEffect_RedChannelGrayscaleHighlight(u8 highlight)
+{
+ u8 i, j;
+
+ for (j = 0; j < gCanvasRowEnd; j++)
+ {
+ u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth];
+ u16 *pixel = &pixelRow[gCanvasColumnStart];
+ for (i = 0; i < gCanvasColumnEnd; i++, pixel++)
+ {
+ if (!(0x8000 & *pixel))
+ {
+ u8 grayValue = (31 & *pixel);
+ if (grayValue > 31 - highlight)
+ grayValue = 31 - (highlight >> 1);
+
+ *pixel = RGB2(grayValue, grayValue, grayValue);
+ }
+ }
+ }
+}
+
+static void ApplyImageEffect_Pointillism(void)
+{
+ u32 i;
+ for (i = 0; i < NELEMS(sPointillismPoints); i++)
+ AddPointillismPoints(i);
+}
+
+static void ApplyImageEffect_Grayscale(void)
+{
+ u8 i, j;
+
+ for (j = 0; j < gCanvasRowEnd; j++)
+ {
+ u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth];
+ u16 *pixel = &pixelRow[gCanvasColumnStart];
+ for (i = 0; i < gCanvasColumnEnd; i++, pixel++)
+ {
+ if (!(0x8000 & *pixel))
+ *pixel = ConvertColorToGrayscale(pixel);
+ }
+ }
+}
+
+static void ApplyImageEffect_Blur(void)
+{
+ u8 i, j;
+
+ for (i = 0; i < gCanvasColumnEnd; i++)
+ {
+ u16 *pixelRow = &(*gCanvasPixels)[0][gCanvasRowStart * gCanvasWidth];
+ u16 *pixel = &pixelRow[gCanvasColumnStart + i];
+ u16 prevPixel = *pixel;
+
+ j = 1;
+ pixel += gCanvasWidth;
+ while (j < gCanvasRowEnd - 1)
+ {
+ if (!(0x8000 & *pixel))
+ {
+ *pixel = QuantizePixel_Blur(&prevPixel, pixel, pixel + gCanvasWidth);
+ prevPixel = *pixel;
+ }
+
+ j++;
+ pixel += gCanvasWidth;
+ }
+ }
+}
+
+static void ApplyImageEffect_PersonalityColor(u8 personality)
+{
+ u8 i, j;
+
+ for (j = 0; j < gCanvasRowEnd; j++)
+ {
+ u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth];
+ u16 *pixel = &pixelRow[gCanvasColumnStart];
+ for (i = 0; i < gCanvasColumnEnd; i++, pixel++)
+ {
+ if (!(0x8000 & *pixel))
+ *pixel = QuantizePixel_PersonalityColor(pixel, personality);
+ }
+ }
+}
+
+static void ApplyImageEffect_BlackAndWhite(void)
+{
+ u8 i, j;
+
+ for (j = 0; j < gCanvasRowEnd; j++)
+ {
+ u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth];
+ u16 *pixel = &pixelRow[gCanvasColumnStart];
+ for (i = 0; i < gCanvasColumnEnd; i++, pixel++)
+ {
+ if (!(0x8000 & *pixel))
+ *pixel = QuantizePixel_BlackAndWhite(pixel);
+ }
+ }
+}
+
+static void ApplyImageEffect_BlackOutline(void)
+{
+ u8 i, j;
+ u16 *pixel;
+
+ // Handle top row of pixels first.
+ for (j = 0; j < gCanvasRowEnd; j++)
+ {
+ u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth];
+ pixel = &pixelRow[gCanvasColumnStart];
+ *pixel = QuantizePixel_BlackOutline(pixel, pixel + 1);
+ for (i = 1, pixel++; i < gCanvasColumnEnd - 1; i++, pixel++)
+ {
+ *pixel = QuantizePixel_BlackOutline(pixel, pixel + 1);
+ *pixel = QuantizePixel_BlackOutline(pixel, pixel - 1);
+ }
+
+ *pixel = QuantizePixel_BlackOutline(pixel, pixel - 1);
+ }
+
+ // Handle each column from left to right.
+ for (i = 0; i < gCanvasColumnEnd; i++)
+ {
+ u16 *pixelRow = &(*gCanvasPixels)[0][gCanvasRowStart * gCanvasWidth];
+ pixel = &pixelRow[gCanvasColumnStart + i];
+ *pixel = QuantizePixel_BlackOutline(pixel, pixel + gCanvasWidth);
+ for (j = 1, pixel += gCanvasWidth; j < gCanvasRowEnd - 1; j++, pixel += gCanvasWidth)
+ {
+ *pixel = QuantizePixel_BlackOutline(pixel, pixel + gCanvasWidth);
+ *pixel = QuantizePixel_BlackOutline(pixel, pixel - gCanvasWidth);
+ }
+
+ *pixel = QuantizePixel_BlackOutline(pixel, pixel - gCanvasWidth);
+ }
+}
+
+static void ApplyImageEffect_Invert(void)
+{
+ u8 i, j;
+
+ for (j = 0; j < gCanvasRowEnd; j++)
+ {
+ u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth];
+ u16 *pixel = &pixelRow[gCanvasColumnStart];
+ for (i = 0; i < gCanvasColumnEnd; i++, pixel++)
+ {
+ if (!(0x8000 & *pixel))
+ *pixel = QuantizePixel_Invert(pixel);
+ }
+ }
+}
+
+static void ApplyImageEffect_Shimmer(void)
+{
+ u8 i, j;
+ u16 *pixel;
+ u16 prevPixel;
+
+ // First, invert all of the colors.
+ pixel = (*gCanvasPixels)[0];
+ for (i = 0; i < 64; i++)
+ {
+ for (j = 0; j < 64; j++, pixel++)
+ {
+ if (!(0x8000 & *pixel))
+ *pixel = QuantizePixel_Invert(pixel);
+ }
+ }
+
+ // Blur the pixels twice.
+ for (j = 0; j < 64; j++)
+ {
+ pixel = &(*gCanvasPixels)[0][j];
+ prevPixel = *pixel;
+ *pixel = 0x8000;
+ for (i = 1, pixel += 64; i < 63; i++, pixel += 64)
+ {
+ if (!(0x8000 & *pixel))
+ {
+ *pixel = QuantizePixel_BlurHard(&prevPixel, pixel, pixel + 64);
+ prevPixel = *pixel;
+ }
+ }
+
+ *pixel = 0x8000;
+ pixel = &(*gCanvasPixels)[0][j];
+ prevPixel = *pixel;
+ *pixel = 0x8000;
+ for (i = 1, pixel += 64; i < 63; i++, pixel += 64)
+ {
+ if (!(0x8000 & *pixel))
+ {
+ *pixel = QuantizePixel_BlurHard(&prevPixel, pixel, pixel + 64);
+ prevPixel = *pixel;
+ }
+ }
+
+ *pixel = 0x8000;
+ }
+
+ // Finally, invert colors back to the original color space.
+ // The above blur causes the outline areas to darken, which makes
+ // this inversion give the effect of light outlines.
+ pixel = (*gCanvasPixels)[0];
+ for (i = 0; i < 64; i++)
+ {
+ for (j = 0; j < 64; j++, pixel++)
+ {
+ if (!(0x8000 & *pixel))
+ *pixel = QuantizePixel_Invert(pixel);
+ }
+ }
+}
+
+static void ApplyImageEffect_BlurRight(void)
+{
+ u8 i, j;
+
+ for (j = 0; j < gCanvasRowEnd; j++)
+ {
+ u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth];
+ u16 *pixel = &pixelRow[gCanvasColumnStart];
+ u16 prevPixel = *pixel;
+ for (i = 1, pixel++; i < gCanvasColumnEnd - 1; i++, pixel++)
+ {
+ if (!(0x8000 & *pixel))
+ {
+ *pixel = QuantizePixel_MotionBlur(&prevPixel, pixel);
+ prevPixel = *pixel;
+ }
+ }
+ }
+}
+
+static void ApplyImageEffect_BlurDown(void)
+{
+ u8 i, j;
+
+ for (i = 0; i < gCanvasColumnEnd; i++)
+ {
+ u16 *pixelRow = &(*gCanvasPixels)[0][gCanvasRowStart * gCanvasWidth];
+ u16 *pixel = &pixelRow[gCanvasColumnStart + i];
+ u16 prevPixel = *pixel;
+ for (j = 1, pixel += gCanvasWidth; j < gCanvasRowEnd - 1; j++, pixel += gCanvasWidth)
+ {
+ if (!(0x8000 & *pixel))
+ {
+ *pixel = QuantizePixel_MotionBlur(&prevPixel, pixel);
+ prevPixel = *pixel;
+ }
+ }
+ }
+}
+
+struct PointillismPoint
+{
+ u8 column;
+ u8 row;
+ u16 delta;
+};
+
+static void AddPointillismPoints(u16 arg0)
+{
+ u8 i;
+ bool8 offsetDownLeft;
+ u8 colorType;
+ struct PointillismPoint points[6];
+
+ points[0].column = sPointillismPoints[arg0][0];
+ points[0].row = sPointillismPoints[arg0][1];
+ points[0].delta = (sPointillismPoints[arg0][2] >> 3) & 7;
+
+ colorType = (sPointillismPoints[arg0][2] >> 1) & 3;
+ offsetDownLeft = sPointillismPoints[arg0][2] & 1;
+ for (i = 1; i < points[0].delta; i++)
+ {
+ if (!offsetDownLeft)
+ {
+ points[i].column = points[0].column - i;
+ points[i].row = points[0].row + i;
+ }
+ else
+ {
+ points[i].column = points[0].column + 1;
+ points[i].row = points[0].row - 1;
+ }
+
+ if (points[i].column > 63 || points[i].row > 63)
+ {
+ points[0].delta = i - 1;
+ break;
+ }
+
+ points[i].delta = points[0].delta - i;
+ }
+
+ for (i = 0; i < points[0].delta; i++)
+ {
+ u16 *pixel = &(*gCanvasPixels)[points[i].row * 2][points[i].column];
+
+ if (!(0x8000 & *pixel))
+ {
+ u16 red = (*pixel) & 0x1F;
+ u16 green = (*pixel >> 5) & 0x1F;
+ u16 blue = (*pixel >> 10) & 0x1F;
+
+ switch (colorType)
+ {
+ case 0:
+ case 1:
+ switch (((sPointillismPoints[arg0][2] >> 3) & 7) % 3)
+ {
+ case 0:
+ if (red >= points[i].delta)
+ red -= points[i].delta;
+ else
+ red = 0;
+ break;
+ case 1:
+ if (green >= points[i].delta)
+ green -= points[i].delta;
+ else
+ green = 0;
+ break;
+ case 2:
+ if (blue >= points[i].delta)
+ blue -= points[i].delta;
+ else
+ blue = 0;
+ break;
+ }
+ break;
+ case 2:
+ case 3:
+ red += points[i].delta;
+ green += points[i].delta;
+ blue += points[i].delta;
+ if (red > 31)
+ red = 31;
+ if (green > 31)
+ green = 31;
+ if (blue > 31)
+ blue = 31;
+ break;
+ }
+
+ *pixel = RGB2(red, green, blue);
+ }
+ }
+}
+
+static u16 ConvertColorToGrayscale(u16 *color)
+{
+ u16 red = *color & 0x1F;
+ u16 green = (*color >> 5) & 0x1F;
+ u16 blue = (*color >> 10) & 0x1F;
+
+ u16 gray = (red + green + blue) / 3;
+ return RGB2(gray, gray, gray);
+}
+
+// The dark colors are the colored edges of the Cool painting effect.
+// Everything else is white.
+static u16 QuantizePixel_PersonalityColor(u16 *color, u8 personality)
+{
+ u16 red = *color & 0x1F;
+ u16 green = (*color >> 5) & 0x1F;
+ u16 blue = (*color >> 10) & 0x1F;
+
+ if (red < 17 && green < 17 && blue < 17)
+ return GetColorFromPersonality(personality);
+ else
+ return RGB_WHITE;
+}
+
+// Based on the given value, which comes from the first 8 bits of
+// the mon's personality value, return a color.
+static u16 GetColorFromPersonality(u8 personality)
+{
+ u16 red = 0;
+ u16 green = 0;
+ u16 blue = 0;
+ u8 strength = (personality / 6) % 3;
+ u8 colorType = personality % 6;
+
+ switch (colorType)
+ {
+ case 0:
+ // Teal color
+ green = 21 - strength;
+ blue = green;
+ red = 0;
+ break;
+ case 1:
+ // Yellow color
+ blue = 0;
+ red = 21 - strength;
+ green = red;
+ break;
+ case 2:
+ // Purple color
+ blue = 21 - strength;
+ green = 0;
+ red = blue;
+ break;
+ case 3:
+ // Red color
+ blue = 0;
+ green = 0;
+ red = 23 - strength;
+ break;
+ case 4:
+ // Blue color
+ blue = 23 - strength;
+ green = 0;
+ red = 0;
+ break;
+ case 5:
+ // Green color
+ blue = 0;
+ green = 23 - strength;
+ red = 0;
+ break;
+ }
+
+ return RGB2(red, green, blue);
+}
+
+static u16 QuantizePixel_BlackAndWhite(u16 *color)
+{
+ u16 red = *color & 0x1F;
+ u16 green = (*color >> 5) & 0x1F;
+ u16 blue = (*color >> 10) & 0x1F;
+
+ if (red < 17 && green < 17 && blue < 17)
+ return RGB_BLACK;
+ else
+ return RGB_WHITE;
+}
+
+static u16 QuantizePixel_BlackOutline(u16 *pixelA, u16 *pixelB)
+{
+ if (*pixelA != RGB_BLACK)
+ {
+ if (*pixelA & 0x8000)
+ return 0x8000;
+ if (*pixelB & 0x8000)
+ return RGB_BLACK;
+
+ return *pixelA;
+ }
+
+ return RGB_BLACK;
+}
+
+static u16 QuantizePixel_Invert(u16 *color)
+{
+ u16 red = *color & 0x1F;
+ u16 green = (*color >> 5) & 0x1F;
+ u16 blue = (*color >> 10) & 0x1F;
+
+ red = 31 - red;
+ green = 31 - green;
+ blue = 31 - blue;
+
+ return RGB2(red, green, blue);
+}
+
+static u16 QuantizePixel_MotionBlur(u16 *prevPixel, u16 *curPixel)
+{
+ u16 pixelChannels[2][3];
+ u16 diffs[3];
+ u8 i;
+ u16 largestDiff;
+ u16 red, green, blue;
+
+ if (*prevPixel == *curPixel)
+ return *curPixel;
+
+ pixelChannels[0][0] = (*prevPixel >> 0) & 0x1F;
+ pixelChannels[0][1] = (*prevPixel >> 5) & 0x1F;
+ pixelChannels[0][2] = (*prevPixel >> 10) & 0x1F;
+ pixelChannels[1][0] = (*curPixel >> 0) & 0x1F;
+ pixelChannels[1][1] = (*curPixel >> 5) & 0x1F;
+ pixelChannels[1][2] = (*curPixel >> 10) & 0x1F;
+
+ // Don't blur light colors.
+ if (pixelChannels[0][0] > 25 && pixelChannels[0][1] > 25 && pixelChannels[0][2] > 25)
+ return *curPixel;
+ if (pixelChannels[1][0] > 25 && pixelChannels[1][1] > 25 && pixelChannels[1][2] > 25)
+ return *curPixel;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (pixelChannels[0][i] > pixelChannels[1][i])
+ diffs[i] = pixelChannels[0][i] - pixelChannels[1][i];
+ else
+ diffs[i] = pixelChannels[1][i] - pixelChannels[0][i];
+ }
+
+ // Find the largest diff of any of the color channels.
+ if (diffs[0] >= diffs[1])
+ {
+ if (diffs[0] >= diffs[2])
+ largestDiff = diffs[0];
+ else if (diffs[1] >= diffs[2])
+ largestDiff = diffs[1];
+ else
+ largestDiff = diffs[2];
+ }
+ else
+ {
+ if (diffs[1] >= diffs[2])
+ largestDiff = diffs[1];
+ else if (diffs[2] >= diffs[0])
+ largestDiff = diffs[2];
+ else
+ largestDiff = diffs[0];
+ }
+
+ red = (pixelChannels[1][0] * (31 - largestDiff / 2)) / 31;
+ green = (pixelChannels[1][1] * (31 - largestDiff / 2)) / 31;
+ blue = (pixelChannels[1][2] * (31 - largestDiff / 2)) / 31;
+ return RGB2(red, green, blue);
+}
+
+static u16 QuantizePixel_Blur(u16 *prevPixel, u16 *curPixel, u16 *nextPixel)
+{
+ u16 red, green, blue;
+ u16 prevAvg, curAvg, nextAvg;
+ u16 prevDiff, nextDiff;
+ u32 diff;
+ u16 factor;
+
+ if (*prevPixel == *curPixel && *nextPixel == *curPixel)
+ return *curPixel;
+
+ red = (*curPixel >> 0) & 0x1F;
+ green = (*curPixel >> 5) & 0x1F;
+ blue = (*curPixel >> 10) & 0x1F;
+
+ prevAvg = (((*prevPixel >> 0) & 0x1F) + ((*prevPixel >> 5) & 0x1F) + ((*prevPixel >> 10) & 0x1F)) / 3;
+ curAvg = (((*curPixel >> 0) & 0x1F) + ((*curPixel >> 5) & 0x1F) + ((*curPixel >> 10) & 0x1F)) / 3;
+ nextAvg = (((*nextPixel >> 0) & 0x1F) + ((*nextPixel >> 5) & 0x1F) + ((*nextPixel >> 10) & 0x1F)) / 3;
+
+ if (prevAvg == curAvg && nextAvg == curAvg)
+ return *curPixel;
+
+ if (prevAvg > curAvg)
+ prevDiff = prevAvg - curAvg;
+ else
+ prevDiff = curAvg - prevAvg;
+
+ if (nextAvg > curAvg)
+ nextDiff = nextAvg - curAvg;
+ else
+ nextDiff = curAvg - nextAvg;
+
+ if (prevDiff >= nextDiff)
+ diff = prevDiff;
+ else
+ diff = nextDiff;
+
+ factor = 31 - diff / 2;
+ red = (red * factor) / 31;
+ green = (green * factor) / 31;
+ blue = (blue * factor) / 31;
+ return RGB2(red, green, blue);
+}
+
+static u16 QuantizePixel_BlurHard(u16 *prevPixel, u16 *curPixel, u16 *nextPixel)
+{
+ u16 red, green, blue;
+ u16 prevAvg, curAvg, nextAvg;
+ u16 prevDiff, nextDiff;
+ u32 diff;
+ u16 factor;
+
+ if (*prevPixel == *curPixel && *nextPixel == *curPixel)
+ return *curPixel;
+
+ red = (*curPixel >> 0) & 0x1F;
+ green = (*curPixel >> 5) & 0x1F;
+ blue = (*curPixel >> 10) & 0x1F;
+
+ prevAvg = (((*prevPixel >> 0) & 0x1F) + ((*prevPixel >> 5) & 0x1F) + ((*prevPixel >> 10) & 0x1F)) / 3;
+ curAvg = (((*curPixel >> 0) & 0x1F) + ((*curPixel >> 5) & 0x1F) + ((*curPixel >> 10) & 0x1F)) / 3;
+ nextAvg = (((*nextPixel >> 0) & 0x1F) + ((*nextPixel >> 5) & 0x1F) + ((*nextPixel >> 10) & 0x1F)) / 3;
+
+ if (prevAvg == curAvg && nextAvg == curAvg)
+ return *curPixel;
+
+ if (prevAvg > curAvg)
+ prevDiff = prevAvg - curAvg;
+ else
+ prevDiff = curAvg - prevAvg;
+
+ if (nextAvg > curAvg)
+ nextDiff = nextAvg - curAvg;
+ else
+ nextDiff = curAvg - nextAvg;
+
+ if (prevDiff >= nextDiff)
+ diff = prevDiff;
+ else
+ diff = nextDiff;
+
+ factor = 31 - diff;
+ red = (red * factor) / 31;
+ green = (green * factor) / 31;
+ blue = (blue * factor) / 31;
+ return RGB2(red, green, blue);
+}
+
+void ConvertImageProcessingToGBA(struct ImageProcessingContext *context)
+{
+ u16 i, j, k;
+ u16 *src, *dest, *src_, *dest_;
+ u16 width, height;
+
+ width = context->canvasWidth >> 3;
+ height = context->canvasHeight >> 3;
+ src_ = context->canvasPixels;
+ dest_ = context->dest;
+
+ if (context->var_16 == 2)
+ {
+ for (i = 0; i < height; i++)
+ {
+ for (j = 0; j < width; j++)
+ {
+ for (k = 0; k < 8; k++)
+ {
+ dest = dest_ + ((i * width + j) << 5) + (k << 2);
+ src = src_ + ((((i << 3) + k) << 3) * width) + (j << 3);
+
+ dest[0] = src[0] | (src[1] << 8);
+ dest[1] = src[2] | (src[3] << 8);
+ dest[2] = src[4] | (src[5] << 8);
+ dest[3] = src[6] | (src[7] << 8);
+ }
+ }
+ }
+ }
+ else
+ {
+ for (i = 0; i < height; i++)
+ {
+ for (j = 0; j < width; j++)
+ {
+ for (k = 0; k < 8; k++)
+ {
+ dest = dest_ + ((i * width + j) << 4) + (k << 1);
+ src = src_ + ((((i << 3) + k) << 3) * width) + (j << 3);
+
+ dest[0] = src[0] | (src[1] << 4) | (src[2] << 8) | (src[3] << 0xC);
+ dest[1] = src[4] | (src[5] << 4) | (src[6] << 8) | (src[7] << 0xC);
+ }
+ }
+ }
+ }
+}
+
+void ApplyImageProcessingQuantization(struct ImageProcessingContext *context)
+{
+ gCanvasPaletteStart = context->paletteStart * 16;
+ gCanvasPalette = &context->canvasPalette[gCanvasPaletteStart];
+ gCanvasPixels = context->canvasPixels;
+ gCanvasColumnStart = context->columnStart;
+ gCanvasRowStart = context->rowStart;
+ gCanvasColumnEnd = context->columnEnd;
+ gCanvasRowEnd = context->rowEnd;
+ gCanvasWidth = context->canvasWidth;
+ gCanvasHeight = context->canvasHeight;
+
+ switch (context->quantizeEffect)
+ {
+ case QUANTIZE_EFFECT_STANDARD:
+ QuantizePalette_Standard(FALSE);
+ break;
+ case QUANTIZE_EFFECT_STANDARD_LIMITED_COLORS:
+ QuantizePalette_Standard(TRUE);
+ break;
+ case QUANTIZE_EFFECT_PRIMARY_COLORS:
+ SetPresetPalette_PrimaryColors();
+ QuantizePalette_PrimaryColors();
+ break;
+ case QUANTIZE_EFFECT_GRAYSCALE:
+ SetPresetPalette_Grayscale();
+ QuantizePalette_Grayscale();
+ break;
+ case QUANTIZE_EFFECT_GRAYSCALE_SMALL:
+ SetPresetPalette_GrayscaleSmall();
+ QuantizePalette_GrayscaleSmall();
+ break;
+ case QUANTIZE_EFFECT_BLACK_WHITE:
+ SetPresetPalette_BlackAndWhite();
+ QuantizePalette_BlackAndWhite();
+ break;
+ }
+}
+
+static void SetPresetPalette_PrimaryColors(void)
+{
+ gCanvasPalette[0] = RGB2(0, 0, 0);
+ gCanvasPalette[1] = RGB2(6, 6, 6);
+ gCanvasPalette[2] = RGB2(29, 29, 29);
+ gCanvasPalette[3] = RGB2(11, 11, 11);
+ gCanvasPalette[4] = RGB2(29, 6, 6);
+ gCanvasPalette[5] = RGB2(6, 29, 6);
+ gCanvasPalette[6] = RGB2(6, 6, 29);
+ gCanvasPalette[7] = RGB2(29, 29, 6);
+ gCanvasPalette[8] = RGB2(29, 6, 29);
+ gCanvasPalette[9] = RGB2(6, 29, 29);
+ gCanvasPalette[10] = RGB2(29, 11, 6);
+ gCanvasPalette[11] = RGB2(11, 29, 6);
+ gCanvasPalette[12] = RGB2(6, 11, 29);
+ gCanvasPalette[13] = RGB2(29, 6, 11);
+ gCanvasPalette[14] = RGB2(6, 29, 11);
+ gCanvasPalette[15] = RGB2(11, 6, 29);
+}
+
+static void SetPresetPalette_BlackAndWhite(void)
+{
+ gCanvasPalette[0] = RGB2(0, 0, 0);
+ gCanvasPalette[1] = RGB2(0, 0, 0);
+ gCanvasPalette[2] = RGB2(31, 31, 31);
+}
+
+static void SetPresetPalette_GrayscaleSmall(void)
+{
+ u8 i;
+
+ gCanvasPalette[0] = RGB2(0, 0, 0);
+ gCanvasPalette[1] = RGB2(0, 0, 0);
+ for (i = 0; i < 14; i++)
+ gCanvasPalette[i + 2] = RGB2(2 * (i + 2), 2 * (i + 2), 2 * (i + 2));
+}
+
+static void SetPresetPalette_Grayscale(void)
+{
+ u8 i;
+
+ gCanvasPalette[0] = RGB2(0, 0, 0);
+ for (i = 0; i < 32; i++)
+ gCanvasPalette[i + 1] = RGB2(i, i, i);
+}
+
+static void QuantizePalette_Standard(bool8 useLimitedPalette)
+{
+ u8 i, j;
+ u16 maxIndex;
+
+ maxIndex = 0xDF;
+ if (!useLimitedPalette)
+ maxIndex = 0xFF;
+
+ for (i = 0; i < maxIndex; i++)
+ gCanvasPalette[i] = RGB_BLACK;
+
+ gCanvasPalette[maxIndex] = RGB2(15, 15, 15);
+ for (j = 0; j < gCanvasRowEnd; j++)
+ {
+ u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth];
+ u16 *pixel = &pixelRow[gCanvasColumnStart];
+ for (i = 0; i < gCanvasColumnEnd; i++, pixel++)
+ {
+ if (*pixel & 0x8000)
+ {
+ *pixel = gCanvasPaletteStart;
+ }
+ else
+ {
+ u16 quantizedColor = QuantizePixel_Standard(pixel);
+ u8 curIndex = 1;
+ if (curIndex < maxIndex)
+ {
+ if (gCanvasPalette[curIndex] == RGB_BLACK)
+ {
+ // The quantized color does not match any existing color in the
+ // palette, so we add it to the palette.
+ // This if block seems pointless because the below while loop handles
+ // this same logic.
+ gCanvasPalette[curIndex] = quantizedColor;
+ *pixel = gCanvasPaletteStart + curIndex;
+ }
+ else
+ {
+ while (curIndex < maxIndex)
+ {
+ if (gCanvasPalette[curIndex] == RGB_BLACK)
+ {
+ // The quantized color does not match any existing color in the
+ // palette, so we add it to the palette.
+ gCanvasPalette[curIndex] = quantizedColor;
+ *pixel = gCanvasPaletteStart + curIndex;
+ break;
+ }
+
+ if (gCanvasPalette[curIndex] == quantizedColor)
+ {
+ // The quantized color matches this existing color in the
+ // palette, so we use this existing color for the pixel.
+ *pixel = gCanvasPaletteStart + curIndex;
+ break;
+ }
+
+ curIndex++;
+ }
+ }
+ }
+
+ if (curIndex == maxIndex)
+ {
+ // The entire palette's colors are already in use, which means
+ // the base image has too many colors to handle. This error is handled
+ // by marking such pixels as gray color.
+ curIndex = maxIndex;
+ *pixel = curIndex;
+ }
+ }
+ }
+ }
+}
+
+static void QuantizePalette_BlackAndWhite(void)
+{
+ u8 i, j;
+
+ for (j = 0; j < gCanvasRowEnd; j++)
+ {
+ u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth];
+ u16 *pixel = &pixelRow[gCanvasColumnStart];
+ for (i = 0; i < gCanvasColumnEnd; i++, pixel++)
+ {
+ if (*pixel & 0x8000)
+ {
+ *pixel = gCanvasPaletteStart;
+ }
+ else
+ {
+ if (QuantizePixel_BlackAndWhite(pixel) == RGB_BLACK)
+ {
+ // Black is the first color in the quantized palette.
+ *pixel = gCanvasPaletteStart + 1;
+ }
+ else
+ {
+ // White is the second color in the quantized palette.
+ *pixel = gCanvasPaletteStart + 2;
+ }
+ }
+ }
+ }
+}
+
+static void QuantizePalette_GrayscaleSmall(void)
+{
+ u8 i, j;
+
+ for (j = 0; j < gCanvasRowEnd; j++)
+ {
+ u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth];
+ u16 *pixel = &pixelRow[gCanvasColumnStart];
+ for (i = 0; i < gCanvasColumnEnd; i++, pixel++)
+ {
+ if (*pixel & 0x8000)
+ *pixel = gCanvasPaletteStart;
+ else
+ *pixel = QuantizePixel_GrayscaleSmall(pixel) + gCanvasPaletteStart;
+ }
+ }
+}
+
+static void QuantizePalette_Grayscale(void)
+{
+ u8 i, j;
+
+ for (j = 0; j < gCanvasRowEnd; j++)
+ {
+ u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth];
+ u16 *pixel = &pixelRow[gCanvasColumnStart];
+ for (i = 0; i < gCanvasColumnEnd; i++, pixel++)
+ {
+ if (*pixel & 0x8000)
+ *pixel = gCanvasPaletteStart;
+ else
+ *pixel = QuantizePixel_Grayscale(pixel) + gCanvasPaletteStart;
+ }
+ }
+}
+
+static void QuantizePalette_PrimaryColors(void)
+{
+ u8 i, j;
+
+ for (j = 0; j < gCanvasRowEnd; j++)
+ {
+ u16 *pixelRow = &(*gCanvasPixels)[0][(gCanvasRowStart + j) * gCanvasWidth];
+ u16 *pixel = &pixelRow[gCanvasColumnStart];
+ for (i = 0; i < gCanvasColumnEnd; i++, pixel++)
+ {
+ if (*pixel & 0x8000)
+ *pixel = gCanvasPaletteStart;
+ else
+ *pixel = QuantizePixel_PrimaryColors(pixel) + gCanvasPaletteStart;
+ }
+ }
+}
+
+// Quantizes the pixel's color channels to nearest multiple of 4, and clamps to [6, 30].
+static u16 QuantizePixel_Standard(u16 *pixel)
+{
+ u16 red = *pixel & 0x1F;
+ u16 green = (*pixel >> 5) & 0x1F;
+ u16 blue = (*pixel >> 10) & 0x1F;
+
+ // Quantize color channels to muliples of 4, rounding up.
+ if (red & 3)
+ red = (red & 0x1C) + 4;
+ if (green & 3)
+ green = (green & 0x1C) + 4;
+ if (blue & 3)
+ blue = (blue & 0x1C) + 4;
+
+ // Clamp channels to [6, 30].
+ if (red < 6)
+ red = 6;
+ if (red > 30)
+ red = 30;
+ if (green < 6)
+ green = 6;
+ if (green > 30)
+ green = 30;
+ if (blue < 6)
+ blue = 6;
+ if (blue > 30)
+ blue = 30;
+
+ return RGB2(red, green, blue);
+}
+
+static u16 QuantizePixel_PrimaryColors(u16* color)
+{
+ u16 red = *color & 0x1F;
+ u16 green = (*color >> 5) & 0x1F;
+ u16 blue = (*color >> 10) & 0x1F;
+
+ if (red < 12 && green < 11 && blue < 11)
+ return 1;
+
+ if (red > 19 && green > 19 && blue > 19)
+ return 2;
+
+ if (red > 19)
+ {
+ if (green > 19)
+ {
+ if (blue > 14)
+ return 2;
+ else
+ return 7;
+ }
+ else if (blue > 19)
+ {
+ if (green > 14)
+ return 2;
+ else
+ return 8;
+ }
+ }
+
+ if (green > 19 && blue > 19)
+ {
+ if (red > 14)
+ return 2;
+ else
+ return 9;
+ }
+
+ if (red > 19)
+ {
+ if (green > 11)
+ {
+ if (blue > 11)
+ {
+ if (green < blue)
+ return 8;
+ else
+ return 7;
+ }
+ else
+ {
+ return 10;
+ }
+ }
+ else if (blue > 11)
+ {
+ return 13;
+ }
+ else
+ {
+ return 4;
+ }
+ }
+
+ if (green > 19)
+ {
+ if (red > 11)
+ {
+ if (blue > 11)
+ {
+ if (red < blue)
+ return 9;
+ else
+ return 7;
+ }
+ else
+ {
+ return 11;
+ }
+ }
+ else
+ {
+ if (blue > 11)
+ return 14;
+ else
+ return 5;
+ }
+ }
+
+ if (blue > 19)
+ {
+ if (red > 11)
+ {
+ if (green > 11)
+ {
+ if (red < green)
+ return 9;
+ else
+ return 8;
+ }
+ }
+ else if (green > 11)
+ {
+ return 12;
+ }
+
+ if (blue > 11)
+ return 15;
+ else
+ return 6;
+ }
+
+ return 3;
+}
+
+static u16 QuantizePixel_GrayscaleSmall(u16 *color)
+{
+ u16 red = *color & 0x1F;
+ u16 green = (*color >> 5) & 0x1F;
+ u16 blue = (*color >> 10) & 0x1F;
+ u16 average = ((red + green + blue) / 3) & 0x1E;
+ if (average == 0)
+ return 1;
+ else
+ return average / 2;
+}
+
+static u16 QuantizePixel_Grayscale(u16 *color)
+{
+ u16 red = *color & 0x1F;
+ u16 green = (*color >> 5) & 0x1F;
+ u16 blue = (*color >> 10) & 0x1F;
+ u16 average = (red + green + blue) / 3;
+ return average + 1;
+}
diff --git a/src/librfu_rfu.c b/src/librfu_rfu.c
new file mode 100644
index 000000000..96de99c2a
--- /dev/null
+++ b/src/librfu_rfu.c
@@ -0,0 +1,2222 @@
+#include "librfu.h"
+
+struct LLSFStruct
+{
+ u8 unk00;
+ u8 unk01;
+ u8 unk02;
+ u8 unk03;
+ u8 unk04;
+ u8 unk05;
+ u8 unk06;
+ u8 unk07;
+ u8 unk08;
+ u8 unk09;
+ u8 unk0A;
+ u8 unk0B;
+ u8 unk0C;
+ u16 unk0E;
+};
+
+struct RfuLocalStruct
+{
+ u8 unk00;
+ u8 unk01;
+ u8 unk02;
+ u8 unk03;
+ u8 unk04;
+ u8 unk05;
+ u16 unk06;
+};
+
+static void rfu_CB_defaultCallback(u8, u16);
+static void rfu_CB_reset(u8, u16);
+static void rfu_CB_configGameData(u8, u16);
+static void rfu_CB_stopMode(u8, u16);
+static void rfu_CB_startSearchChild(u8, u16);
+static void rfu_CB_pollAndEndSearchChild(u8, u16);
+static void rfu_CB_startSearchParent(u8, u16);
+static void rfu_CB_pollSearchParent(u8, u16);
+static void rfu_CB_pollConnectParent(u8, u16);
+static void rfu_CB_pollConnectParent(u8, u16);
+static void rfu_CB_disconnect(u8, u16);
+static void rfu_CB_CHILD_pollConnectRecovery(u8, u16);
+static void rfu_CB_sendData(UNUSED u8, u16);
+static void rfu_CB_sendData2(UNUSED u8, u16);
+static void rfu_CB_sendData3(u8, u16);
+static void rfu_CB_recvData(u8, u16);
+static void rfu_enableREQCallback(bool8);
+static void rfu_STC_clearAPIVariables(void);
+static void rfu_STC_readChildList(void);
+static void rfu_STC_readParentCandidateList(void);
+static void rfu_STC_REQ_callback(u8, u16);
+static void rfu_STC_removeLinkData(u8, u8);
+static void rfu_STC_fastCopy(const u8 **, u8 **, s32);
+static void rfu_STC_clearLinkStatus(u8);
+static void rfu_NI_checkCommFailCounter(void);
+static u16 rfu_STC_setSendData_org(u8, u8, u8, const void *, u32);
+static void rfu_constructSendLLFrame(void);
+static u16 rfu_STC_NI_constructLLSF(u8, u8 **, struct NIComm *);
+static u16 rfu_STC_UNI_constructLLSF(u8, u8 **);
+static void rfu_STC_PARENT_analyzeRecvPacket(void);
+static void rfu_STC_CHILD_analyzeRecvPacket(void);
+static u16 rfu_STC_analyzeLLSF(u8, const u8 *, u16);
+static void rfu_STC_UNI_receive(u8, const struct RfuLocalStruct *, const u8 *);
+static void rfu_STC_NI_receive_Receiver(u8, const struct RfuLocalStruct *, const u8 *);
+static void rfu_STC_NI_receive_Sender(u8, u8, const struct RfuLocalStruct *, UNUSED const u8 *);
+static void rfu_STC_NI_initSlot_asRecvDataEntity(u8, struct NIComm *);
+static void rfu_STC_NI_initSlot_asRecvControllData(u8, struct NIComm *);
+
+struct RfuSlotStatusUNI *gRfuSlotStatusUNI[RFU_CHILD_MAX];
+struct RfuSlotStatusNI *gRfuSlotStatusNI[RFU_CHILD_MAX];
+struct RfuLinkStatus *gRfuLinkStatus;
+struct RfuStatic *gRfuStatic;
+struct RfuFixed *gRfuFixed;
+
+static const struct LLSFStruct llsf_struct[2] = {
+ {
+ 2, 14, 0, 10, 9, 5, 7, 2,
+ 0, 15, 1, 3, 3, 0x1f
+ }, {
+ 3, 22, 18, 14, 13, 9, 11, 3,
+ 15, 15, 1, 3, 3, 0x7f
+ }
+};
+
+#ifdef EMERALD
+static const char lib_ver[] = "RFU_V1026";
+#else
+static const char lib_ver[] = "RFU_V1024";
+#endif
+
+static const char str_checkMbootLL[] = "RFU-MBOOT";
+
+u16 rfu_initializeAPI(struct RfuAPIBuffer *APIBuffer, u16 buffByteSize, IntrFunc *sioIntrTable_p, bool8 copyInterruptToRam)
+{
+ u16 i;
+ u16 *dst;
+ const u16 *src;
+ u16 r3;
+
+ // is in EWRAM?
+ if (((u32)APIBuffer & 0xF000000) == 0x2000000 && copyInterruptToRam)
+ return ERR_RFU_API_BUFF_ADR;
+ // is not 4-byte aligned?
+ if ((u32)APIBuffer & 3)
+ return ERR_RFU_API_BUFF_ADR;
+ if (copyInterruptToRam)
+ {
+ // An assert/debug print may have existed before, ie
+ // printf("%s %u < %u", "somefile.c:12345", buffByteSize, num)
+ // to push this into r3?
+ r3 = sizeof(struct RfuAPIBuffer);
+ if (buffByteSize < r3)
+ return ERR_RFU_API_BUFF_SIZE;
+ }
+ if (!copyInterruptToRam)
+ {
+ r3 = 0x504; // same issue as above
+ if (buffByteSize < r3)
+ return ERR_RFU_API_BUFF_SIZE;
+ }
+ gRfuLinkStatus = &APIBuffer->linkStatus;
+ gRfuStatic = &APIBuffer->static_;
+ gRfuFixed = &APIBuffer->fixed;
+ gRfuSlotStatusNI[0] = &APIBuffer->NI[0];
+ gRfuSlotStatusUNI[0] = &APIBuffer->UNI[0];
+ for (i = 1; i < RFU_CHILD_MAX; ++i)
+ {
+ gRfuSlotStatusNI[i] = &gRfuSlotStatusNI[i - 1][1];
+ gRfuSlotStatusUNI[i] = &gRfuSlotStatusUNI[i - 1][1];
+ }
+ // TODO: Is it possible to fix the following 2 statements?
+ // It's equivalent to:
+ // gRfuFixed->STWIBuffer = &APIBuffer->intr;
+ // STWI_init_all(&APIBuffer->intr, sioIntrTable_p, copyInterruptToRam);
+ gRfuFixed->STWIBuffer = (struct RfuIntrStruct *)&gRfuSlotStatusUNI[3][1];
+ STWI_init_all((struct RfuIntrStruct *)&gRfuSlotStatusUNI[3][1], sioIntrTable_p, copyInterruptToRam);
+ rfu_STC_clearAPIVariables();
+ for (i = 0; i < RFU_CHILD_MAX; ++i)
+ {
+ gRfuSlotStatusNI[i]->recvBuffer = NULL;
+ gRfuSlotStatusNI[i]->recvBufferSize = 0;
+ gRfuSlotStatusUNI[i]->recvBuffer = NULL;
+ gRfuSlotStatusUNI[i]->recvBufferSize = 0;
+ }
+ src = (const u16 *)((u32)&rfu_STC_fastCopy & ~1);
+ dst = gRfuFixed->fastCopyBuffer;
+ // rfu_REQ_changeMasterSlave is the function next to rfu_STC_fastCopy
+ for (r3 = ((void *)rfu_REQ_changeMasterSlave - (void *)rfu_STC_fastCopy) / sizeof(u16), --r3; r3 != 0xFFFF; --r3)
+ *dst++ = *src++;
+ gRfuFixed->fastCopyPtr = (void *)gRfuFixed->fastCopyBuffer + 1;
+ return 0;
+}
+
+static void rfu_STC_clearAPIVariables(void)
+{
+ u16 IMEBackup = REG_IME;
+ u8 i, r4;
+
+ REG_IME = 0;
+ r4 = gRfuStatic->flags;
+ CpuFill16(0, gRfuStatic, sizeof(struct RfuStatic));
+ gRfuStatic->flags = r4 & 8;
+ CpuFill16(0, gRfuLinkStatus, sizeof(struct RfuLinkStatus));
+ gRfuLinkStatus->watchInterval = 4;
+ gRfuStatic->nowWatchInterval = 0;
+ gRfuLinkStatus->parentChild = MODE_NEUTRAL;
+ rfu_clearAllSlot();
+ gRfuStatic->SCStartFlag = 0;
+ for (i = 0; i < NELEMS(gRfuStatic->cidBak); ++i)
+ gRfuStatic->cidBak[i] = 0;
+ REG_IME = IMEBackup;
+}
+
+void rfu_REQ_PARENT_resumeRetransmitAndChange(void)
+{
+ STWI_set_Callback_M(rfu_STC_REQ_callback);
+ STWI_send_ResumeRetransmitAndChangeREQ();
+}
+
+u16 rfu_UNI_PARENT_getDRAC_ACK(u8 *ackFlag)
+{
+ struct RfuIntrStruct *buf;
+
+ *ackFlag = 0;
+ if (gRfuLinkStatus->parentChild != MODE_PARENT)
+ return ERR_MODE_NOT_PARENT;
+ buf = rfu_getSTWIRecvBuffer();
+ switch (buf->rxPacketAlloc.rfuPacket8.data[0])
+ {
+ case 40:
+ case 54:
+ if (buf->rxPacketAlloc.rfuPacket8.data[1] == 0)
+ *ackFlag = gRfuLinkStatus->connSlotFlag;
+ else
+ *ackFlag = buf->rxPacketAlloc.rfuPacket8.data[4];
+ return 0;
+ default:
+ return ERR_REQ_CMD_ID;
+ }
+}
+
+void rfu_setTimerInterrupt(u8 timerNo, IntrFunc *timerIntrTable_p)
+{
+ STWI_init_timer(timerIntrTable_p, timerNo);
+}
+
+struct RfuIntrStruct *rfu_getSTWIRecvBuffer(void)
+{
+ return gRfuFixed->STWIBuffer;
+}
+
+void rfu_setMSCCallback(void (*callback)(u16 reqCommandId))
+{
+ STWI_set_Callback_S(callback);
+}
+
+void rfu_setREQCallback(void (*callback)(u16 reqCommandId, u16 reqResult))
+{
+ gRfuFixed->reqCallback = callback;
+ rfu_enableREQCallback(callback != NULL);
+}
+
+static void rfu_enableREQCallback(bool8 enable)
+{
+ if (enable)
+ gRfuStatic->flags |= 8;
+ else
+ gRfuStatic->flags &= 0xF7;
+}
+
+static void rfu_STC_REQ_callback(u8 r5, u16 reqResult)
+{
+ STWI_set_Callback_M(rfu_CB_defaultCallback);
+ gRfuStatic->reqResult = reqResult;
+ if (gRfuStatic->flags & 8)
+ gRfuFixed->reqCallback(r5, reqResult);
+}
+
+static void rfu_CB_defaultCallback(u8 r0, u16 reqResult)
+{
+ s32 r5;
+ u8 i;
+
+ if (r0 == 0xFF)
+ {
+ if (gRfuStatic->flags & 8)
+ gRfuFixed->reqCallback(r0, reqResult);
+ r5 = gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag;
+ for (i = 0; i < RFU_CHILD_MAX; ++i)
+ if ((r5 >> i) & 1)
+ rfu_STC_removeLinkData(i, 1);
+ gRfuLinkStatus->parentChild = MODE_NEUTRAL;
+ }
+}
+
+u16 rfu_waitREQComplete(void)
+{
+ STWI_poll_CommandEnd();
+ return gRfuStatic->reqResult;
+}
+
+void rfu_REQ_RFUStatus(void)
+{
+ STWI_set_Callback_M(rfu_STC_REQ_callback);
+ STWI_send_SystemStatusREQ();
+}
+
+u16 rfu_getRFUStatus(u8 *rfuState)
+{
+ if (gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[0] != 0x93)
+ return ERR_REQ_CMD_ID;
+ if (STWI_poll_CommandEnd() == 0)
+ *rfuState = gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[7];
+ else
+ *rfuState = 0xFF;
+ return 0;
+}
+
+u16 rfu_MBOOT_CHILD_inheritanceLinkStatus(void)
+{
+ const char *s1 = str_checkMbootLL;
+ char *s2 = (char *)0x30000F0;
+ u16 checksum;
+ u16 *r2;
+ u8 i;
+
+ while (*s1 != '\0')
+ if (*s1++ != *s2++)
+ return 1;
+ r2 = (u16 *)0x3000000;
+ checksum = 0;
+ for (i = 0; i < 90; ++i)
+ checksum += *r2++;
+ if (checksum != *(u16 *)0x30000FA)
+ return 1;
+ CpuCopy16((u16 *)0x3000000, gRfuLinkStatus, sizeof(struct RfuLinkStatus));
+ gRfuStatic->flags |= 0x80;
+ return 0;
+}
+
+void rfu_REQ_stopMode(void)
+{
+ vu32 *timerReg;
+
+ if (REG_IME == 0)
+ {
+ rfu_STC_REQ_callback(61, 6);
+ gSTWIStatus->error = ERR_REQ_CMD_IME_DISABLE;
+ }
+ else
+ {
+ AgbRFU_SoftReset();
+ rfu_STC_clearAPIVariables();
+ if (AgbRFU_checkID(8) == 0x8001)
+ {
+ timerReg = &REG_TMCNT(gSTWIStatus->timerSelect);
+ *timerReg = 0;
+ *timerReg = (TIMER_ENABLE | TIMER_1024CLK) << 16;
+ while (*timerReg << 16 < 262 << 16)
+ ;
+ *timerReg = 0;
+ STWI_set_Callback_M(rfu_CB_stopMode);
+ STWI_send_StopModeREQ();
+ }
+ else
+ {
+ REG_SIOCNT = SIO_MULTI_MODE;
+ rfu_STC_REQ_callback(61, 0);
+ }
+ }
+}
+
+static void rfu_CB_stopMode(u8 a1, u16 reqResult)
+{
+ if (reqResult == 0)
+ REG_SIOCNT = SIO_MULTI_MODE;
+ rfu_STC_REQ_callback(a1, reqResult);
+}
+
+u32 rfu_REQBN_softReset_and_checkID(void)
+{
+ u32 r2;
+
+ if (REG_IME == 0)
+ return ERR_ID_CHECK_IME_DISABLE;
+ AgbRFU_SoftReset();
+ rfu_STC_clearAPIVariables();
+ if ((r2 = AgbRFU_checkID(30)) == 0)
+ REG_SIOCNT = SIO_MULTI_MODE;
+ return r2;
+}
+
+void rfu_REQ_reset(void)
+{
+ STWI_set_Callback_M(rfu_CB_reset);
+ STWI_send_ResetREQ();
+}
+
+static void rfu_CB_reset(u8 a1, u16 reqResult)
+{
+ if (reqResult == 0)
+ rfu_STC_clearAPIVariables();
+ rfu_STC_REQ_callback(a1, reqResult);
+}
+
+void rfu_REQ_configSystem(u16 availSlotFlag, u8 maxMFrame, u8 mcTimer)
+{
+ STWI_set_Callback_M(rfu_STC_REQ_callback);
+ STWI_send_SystemConfigREQ((availSlotFlag & AVAIL_SLOT1) | 0x3C, maxMFrame, mcTimer);
+ if (mcTimer == 0)
+ {
+ gRfuStatic->unk_1a = 1;
+ }
+ else
+ {
+ u16 IMEBackup = REG_IME;
+
+ REG_IME = 0;
+ gRfuStatic->unk_1a = Div(600, mcTimer);
+ REG_IME = IMEBackup;
+ }
+}
+
+void rfu_REQ_configGameData(u8 mbootFlag, u16 serialNo, const u8 *gname, const u8 *uname)
+{
+ u8 sp[16];
+ u8 i;
+ u8 r3;
+ const u8 *gnameBackup = gname;
+ const u8 *unameBackup;
+
+ sp[0] = serialNo;
+ sp[1] = serialNo >> 8;
+ if (mbootFlag != 0)
+ sp[1] = (serialNo >> 8) | 0x80;
+ for (i = 2; i < 15; ++i)
+ sp[i] = *gname++;
+ r3 = 0;
+ unameBackup = uname;
+ for (i = 0; i < 8; ++i)
+ {
+ r3 += *unameBackup++;
+ r3 += *gnameBackup++;
+ }
+ sp[15] = ~r3;
+ if (mbootFlag != 0)
+ sp[14] = 0;
+ STWI_set_Callback_M(rfu_CB_configGameData);
+ STWI_send_GameConfigREQ(sp, uname);
+}
+
+static void rfu_CB_configGameData(u8 ip, u16 r7)
+{
+ s32 r2, r3;
+ u8 *r4;
+ u8 i;
+ u8 *r1;
+
+ if (r7 == 0)
+ {
+ r1 = gSTWIStatus->txPacket->rfuPacket8.data;
+ r2 = gRfuLinkStatus->my.serialNo = r1[4];
+ gRfuLinkStatus->my.serialNo = (r1[5] << 8) | r2;
+ r4 = &r1[6];
+ if (gRfuLinkStatus->my.serialNo & 0x8000)
+ {
+ gRfuLinkStatus->my.serialNo = gRfuLinkStatus->my.serialNo ^ 0x8000;
+ gRfuLinkStatus->my.mbootFlag = 1;
+ }
+ else
+ {
+ gRfuLinkStatus->my.mbootFlag = 0;
+ }
+ for (i = 0; i < RFU_GAME_NAME_LENGTH; ++i)
+ gRfuLinkStatus->my.gname[i] = *r4++;
+ ++r4;
+ for (i = 0; i < RFU_USER_NAME_LENGTH; ++i)
+ gRfuLinkStatus->my.uname[i] = *r4++;
+ }
+ rfu_STC_REQ_callback(ip, r7);
+}
+
+void rfu_REQ_startSearchChild(void)
+{
+ u16 r1;
+
+ STWI_set_Callback_M(rfu_CB_defaultCallback);
+ STWI_send_SystemStatusREQ();
+ r1 = STWI_poll_CommandEnd();
+ if (r1 == 0)
+ {
+ if (gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[7] == 0)
+ rfu_STC_clearLinkStatus(1);
+ }
+ else
+ {
+ rfu_STC_REQ_callback(25, r1);
+ }
+ STWI_set_Callback_M(rfu_CB_startSearchChild);
+ STWI_send_SC_StartREQ();
+}
+
+static void rfu_CB_startSearchChild(u8 r3, u16 reqResult)
+{
+ if (reqResult == 0)
+ gRfuStatic->SCStartFlag = 1;
+ rfu_STC_REQ_callback(r3, reqResult);
+}
+
+static void rfu_STC_clearLinkStatus(u8 r4)
+{
+ u8 i;
+
+ rfu_clearAllSlot();
+ if (r4 != 0)
+ {
+ CpuFill16(0, gRfuLinkStatus->partner, sizeof(gRfuLinkStatus->partner));
+ gRfuLinkStatus->findParentCount = 0;
+ }
+ for (i = 0; i < RFU_CHILD_MAX; ++i)
+ gRfuLinkStatus->strength[i] = 0;
+ gRfuLinkStatus->connCount = 0;
+ gRfuLinkStatus->connSlotFlag = 0;
+ gRfuLinkStatus->linkLossSlotFlag = 0;
+ gRfuLinkStatus->getNameFlag = 0;
+}
+
+void rfu_REQ_pollSearchChild(void)
+{
+ STWI_set_Callback_M(rfu_CB_pollAndEndSearchChild);
+ STWI_send_SC_PollingREQ();
+}
+
+void rfu_REQ_endSearchChild(void)
+{
+ STWI_set_Callback_M(rfu_CB_pollAndEndSearchChild);
+ STWI_send_SC_EndREQ();
+}
+
+static void rfu_CB_pollAndEndSearchChild(u8 r4, u16 reqResult)
+{
+ if (reqResult == 0)
+ rfu_STC_readChildList();
+ if (r4 == 26)
+ {
+ if (gRfuLinkStatus->my.id == 0)
+ {
+ STWI_set_Callback_M(rfu_CB_defaultCallback);
+ STWI_send_SystemStatusREQ();
+ if (STWI_poll_CommandEnd() == 0)
+ gRfuLinkStatus->my.id = *(u16 *)&gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket32.data[0];
+ }
+ }
+ else if (r4 == 27)
+ {
+ if (gRfuLinkStatus->parentChild == MODE_NEUTRAL)
+ gRfuLinkStatus->my.id = 0;
+ gRfuStatic->SCStartFlag = 0;
+ }
+ rfu_STC_REQ_callback(r4, reqResult);
+}
+
+static void rfu_STC_readChildList(void)
+{
+ u32 r5;
+ u8 r8 = gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[1];
+ u8 *r4;
+ u8 i;
+ u8 sp[4];
+ u8 r2;
+
+ if (r8 != 0)
+ {
+ r5 = gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket32.data[0];
+ STWI_set_Callback_M(rfu_CB_defaultCallback);
+ STWI_send_LinkStatusREQ();
+ if (STWI_poll_CommandEnd() == 0)
+ {
+ r4 = &gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[4];
+ for (i = 0; i < NELEMS(sp); ++i)
+ sp[i] = *r4++;
+ }
+ gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket32.data[0] = r5;
+ }
+ for (r4 = &gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[4];
+ r8 != 0;
+ r4 += 4)
+ {
+ r2 = r4[2];
+ if (r2 < RFU_CHILD_MAX && !((gRfuLinkStatus->connSlotFlag >> r2) & 1) && !((gRfuLinkStatus->linkLossSlotFlag >> r2) & 1))
+ {
+ if (sp[r2] != 0)
+ ++gRfuStatic->lsFixedCount[r2];
+ if (gRfuStatic->lsFixedCount[r2] >= 4)
+ {
+ gRfuStatic->lsFixedCount[r2] = 0;
+ gRfuLinkStatus->strength[r2] = 0xFF;
+ gRfuLinkStatus->connSlotFlag |= 1 << r2;
+ ++gRfuLinkStatus->connCount;
+ gRfuLinkStatus->partner[r2].id = *(u16 *)r4;
+ gRfuLinkStatus->partner[r2].slot = r2;
+ gRfuLinkStatus->parentChild = MODE_PARENT;
+ gRfuStatic->flags &= 0x7F;
+ gRfuStatic->cidBak[r2] = gRfuLinkStatus->partner[r2].id;
+ }
+ }
+ --r8;
+ }
+}
+
+void rfu_REQ_startSearchParent(void)
+{
+ STWI_set_Callback_M(rfu_CB_startSearchParent);
+ STWI_send_SP_StartREQ();
+}
+
+static void rfu_CB_startSearchParent(u8 r5, u16 reqResult)
+{
+ if (reqResult == 0)
+ rfu_STC_clearLinkStatus(0);
+ rfu_STC_REQ_callback(r5, reqResult);
+}
+
+void rfu_REQ_pollSearchParent(void)
+{
+ STWI_set_Callback_M(rfu_CB_pollSearchParent);
+ STWI_send_SP_PollingREQ();
+}
+
+static void rfu_CB_pollSearchParent(u8 r5, u16 reqResult)
+{
+ if (reqResult == 0)
+ rfu_STC_readParentCandidateList();
+ rfu_STC_REQ_callback(r5, reqResult);
+}
+
+void rfu_REQ_endSearchParent(void)
+{
+ STWI_set_Callback_M(rfu_STC_REQ_callback);
+ STWI_send_SP_EndREQ();
+}
+
+static void rfu_STC_readParentCandidateList(void)
+{
+ u8 r7, r6, r5, r4, r3;
+ u8 *r1, *r2;
+ struct RfuTgtData *r4_;
+
+ CpuFill16(0, gRfuLinkStatus->partner, sizeof(gRfuLinkStatus->partner));
+ r2 = &gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[0];
+ r7 = r2[1];
+ r2 += 4;
+ gRfuLinkStatus->findParentCount = 0;
+ for (r6 = 0; r6 < 4 && r7 != 0; ++r6)
+ {
+ r7 -= 7;
+ r1 = r2 + 6;
+ r2 += 19;
+ r5 = ~*r2;
+ ++r2;
+ r4 = 0;
+ for (r3 = 0; r3 < 8; ++r3)
+ {
+ r4 += *r2++;
+ r4 += *r1++;
+ }
+ if (r4 == r5)
+ {
+ r2 -= 28;
+ r4_ = &gRfuLinkStatus->partner[gRfuLinkStatus->findParentCount];
+ r4_->id = *(u16 *)r2;
+ r2 += 2;
+ r4_->slot = *r2;
+ r2 += 2;
+ r4_->serialNo = *(u16 *)r2 & 0x7FFF;
+ if (*(u16 *)r2 & 0x8000)
+ r4_->mbootFlag = 1;
+ else
+ r4_->mbootFlag = 0;
+ r2 += 2;
+ for (r3 = 0; r3 < RFU_GAME_NAME_LENGTH; ++r3)
+ r4_->gname[r3] = *r2++;
+ ++r2;
+ for (r3 = 0; r3 < RFU_USER_NAME_LENGTH; ++r3)
+ r4_->uname[r3] = *r2++;
+ ++gRfuLinkStatus->findParentCount;
+ }
+ }
+}
+
+void rfu_REQ_startConnectParent(u16 pid)
+{
+ u16 r3 = 0;
+ u8 i;
+ for (i = 0; i < RFU_CHILD_MAX && gRfuLinkStatus->partner[i].id != pid; ++i)
+ ;
+ if (i == 4)
+ r3 = 256;
+ if (r3 == 0)
+ {
+ gRfuStatic->tryPid = pid;
+ STWI_set_Callback_M(rfu_STC_REQ_callback);
+ STWI_send_CP_StartREQ(pid);
+ }
+ else
+ {
+ rfu_STC_REQ_callback(31, r3);
+ }
+}
+
+void rfu_REQ_pollConnectParent(void)
+{
+ STWI_set_Callback_M(rfu_CB_pollConnectParent);
+ STWI_send_CP_PollingREQ();
+}
+
+static void rfu_CB_pollConnectParent(u8 sp24, u16 sp28)
+{
+ u16 id;
+ u8 slot;
+ u8 r2, r5;
+ struct RfuTgtData *r9;
+ struct RfuTgtData sp;
+
+ if (sp28 == 0)
+ {
+ id = gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket32.data[0];
+ slot = gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[6];
+ if (gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[7] == 0)
+ {
+ r2 = 1 << slot;
+ if (!(r2 & gRfuLinkStatus->connSlotFlag))
+ {
+ gRfuLinkStatus->connSlotFlag |= r2;
+ gRfuLinkStatus->linkLossSlotFlag &= ~r2;
+ gRfuLinkStatus->my.id = id;
+ ++gRfuLinkStatus->connCount;
+ gRfuLinkStatus->parentChild = MODE_CHILD;
+ gRfuStatic->flags |= 0x80;
+ for (r5 = 0; r5 < RFU_CHILD_MAX; ++r5)
+ {
+ if (gRfuLinkStatus->partner[r5].id == gRfuStatic->tryPid)
+ {
+ if (gRfuLinkStatus->findParentCount != 0)
+ {
+ r9 = &sp;
+ CpuCopy16(&gRfuLinkStatus->partner[r5], &sp, sizeof(struct RfuTgtData));
+ CpuFill16(0, gRfuLinkStatus->partner, sizeof(gRfuLinkStatus->partner));
+ gRfuLinkStatus->findParentCount = 0;
+ }
+ else
+ {
+ r9 = &gRfuLinkStatus->partner[r5];
+ }
+ break;
+ }
+ }
+ if (r5 < RFU_CHILD_MAX)
+ {
+ CpuCopy16(r9, &gRfuLinkStatus->partner[slot], sizeof(struct RfuTgtData));
+ gRfuLinkStatus->partner[slot].slot = slot;
+ }
+ }
+ }
+ }
+ rfu_STC_REQ_callback(sp24, sp28);
+}
+
+u16 rfu_getConnectParentStatus(u8 *status, u8 *connectSlotNo)
+{
+ u8 r0, *r2;
+
+ *status = 0xFF;
+ r2 = gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data;
+ r0 = r2[0] + 96;
+ if (r0 <= 1)
+ {
+ r2 += 6;
+ *connectSlotNo = r2[0];
+ *status = r2[1];
+ return 0;
+ }
+ return ERR_REQ_CMD_ID;
+}
+
+void rfu_REQ_endConnectParent(void)
+{
+ STWI_set_Callback_M(rfu_CB_pollConnectParent);
+ STWI_send_CP_EndREQ();
+ if (gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[6] < 4)
+ gRfuStatic->linkEmergencyFlag[gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[6]] = 0;
+}
+
+u16 rfu_syncVBlank(void)
+{
+ u8 r3, r4;
+ s32 r5;
+
+ rfu_NI_checkCommFailCounter();
+ if (gRfuLinkStatus->parentChild == MODE_NEUTRAL)
+ return 0;
+ if (gRfuStatic->nowWatchInterval != 0)
+ --gRfuStatic->nowWatchInterval;
+ r3 = rfu_getMasterSlave();
+ if (!(gRfuStatic->flags & 2))
+ {
+ if (r3 == 0)
+ {
+ gRfuStatic->flags |= 4;
+ gRfuStatic->watchdogTimer = 360;
+ }
+ }
+ else if (r3 != 0)
+ {
+ gRfuStatic->flags &= 0xFB;
+ }
+ if (r3 != 0)
+ gRfuStatic->flags &= 0xFD;
+ else
+ gRfuStatic->flags |= 2;
+ if (!(gRfuStatic->flags & 4))
+ return 0;
+ if (gRfuStatic->watchdogTimer == 0)
+ {
+ gRfuStatic->flags &= 0xFB;
+ r5 = gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag;
+ for (r4 = 0; r4 < RFU_CHILD_MAX; ++r4)
+ if ((r5 >> r4) & 1)
+ rfu_STC_removeLinkData(r4, 1);
+ gRfuLinkStatus->parentChild = MODE_NEUTRAL;
+ return 1;
+ }
+ --gRfuStatic->watchdogTimer;
+ return 0;
+}
+
+u16 rfu_REQBN_watchLink(u16 reqCommandId, u8 *bmLinkLossSlot, u8 *linkLossReason, u8 *parentBmLinkRecoverySlot)
+{
+ u8 sp08 = 0;
+ u8 sp0C = 0;
+ u8 i;
+ s32 sp10, sp14;
+ u8 *r2;
+ u8 r9, r6, r3, connSlotFlag, r0;
+
+ *bmLinkLossSlot = 0;
+ *linkLossReason = REASON_DISCONNECTED;
+ *parentBmLinkRecoverySlot = 0;
+ if (gRfuLinkStatus->parentChild == MODE_NEUTRAL || gSTWIStatus->msMode == 0)
+ return 0;
+ if (gRfuStatic->flags & 4)
+ gRfuStatic->watchdogTimer = 360;
+ if (gRfuStatic->nowWatchInterval == 0)
+ {
+ gRfuStatic->nowWatchInterval = gRfuLinkStatus->watchInterval;
+ sp08 = 1;
+ }
+ if ((u8)reqCommandId == 41)
+ {
+ u8 *r1 = gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data;
+
+ *bmLinkLossSlot = r1[4];
+ *linkLossReason = r1[5];
+ if (*linkLossReason == REASON_LINK_LOSS)
+ *bmLinkLossSlot = gRfuLinkStatus->connSlotFlag;
+ sp08 = 2;
+ }
+ else
+ {
+ if (reqCommandId == 310)
+ {
+ r6 = gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[5];
+ r6 ^= gRfuLinkStatus->connSlotFlag;
+ *bmLinkLossSlot = r6 & gRfuLinkStatus->connSlotFlag;
+ *linkLossReason = REASON_LINK_LOSS;
+ for (i = 0; i < RFU_CHILD_MAX; ++i)
+ {
+ if ((*bmLinkLossSlot >> i) & 1)
+ {
+ gRfuLinkStatus->strength[i] = 0;
+ rfu_STC_removeLinkData(i, 0);
+ }
+ }
+ }
+ if (sp08 == 0)
+ return 0;
+ }
+ sp10 = gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket32.command;
+ sp14 = gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket32.data[0];
+ STWI_set_Callback_M(rfu_CB_defaultCallback);
+ STWI_send_LinkStatusREQ();
+ sp0C = STWI_poll_CommandEnd();
+ if (sp0C == 0)
+ {
+ r2 = &gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[4];
+ for (i = 0; i < RFU_CHILD_MAX; ++i)
+ gRfuLinkStatus->strength[i] = *r2++;
+ r9 = 0;
+ i = 0;
+ }
+ else
+ {
+ rfu_STC_REQ_callback(17, sp0C);
+ return sp0C;
+ }
+ for (; i < RFU_CHILD_MAX; ++i)
+ {
+ r6 = 1 << i;
+ if (sp0C == 0)
+ {
+ if (sp08 == 1 && (gRfuLinkStatus->connSlotFlag & r6))
+ {
+ if (gRfuLinkStatus->strength[i] == 0)
+ {
+ if (gRfuLinkStatus->parentChild == MODE_PARENT)
+ {
+ ++gRfuStatic->linkEmergencyFlag[i];
+ if (gRfuStatic->linkEmergencyFlag[i] > 3)
+ {
+ *bmLinkLossSlot |= r6;
+ *linkLossReason = sp08; // why not directly use REASON_LINK_LOSS?
+ }
+ }
+ else
+ {
+ STWI_send_SystemStatusREQ();
+ if (STWI_poll_CommandEnd() == 0)
+ {
+ if (gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[7] == 0)
+ {
+ *bmLinkLossSlot |= r6;
+ *linkLossReason = sp08; // why not directly use REASON_LINK_LOSS?
+ }
+ else
+ {
+ if (++gRfuStatic->linkEmergencyFlag[i] > gRfuStatic->unk_1a)
+ {
+ gRfuStatic->linkEmergencyFlag[i] = 0;
+ STWI_send_DisconnectREQ(gRfuLinkStatus->connSlotFlag);
+ STWI_poll_CommandEnd();
+ *bmLinkLossSlot |= r6;
+ *linkLossReason = sp08; // why not directly use REASON_LINK_LOSS?
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ gRfuStatic->linkEmergencyFlag[i] = sp0C; // why not directly use 0?
+ }
+ }
+ if (gRfuLinkStatus->parentChild == MODE_PARENT && gRfuLinkStatus->strength[i] != 0)
+ {
+ if (r6 & gRfuLinkStatus->linkLossSlotFlag)
+ {
+ if (gRfuLinkStatus->strength[i] > 10)
+ {
+ *parentBmLinkRecoverySlot |= r6;
+ gRfuLinkStatus->connSlotFlag |= r6;
+ gRfuLinkStatus->linkLossSlotFlag &= ~r6;
+ ++gRfuLinkStatus->connCount;
+ gRfuStatic->linkEmergencyFlag[i] = 0;
+ }
+ else
+ {
+ gRfuLinkStatus->strength[i] = 0;
+ }
+ }
+ else
+ {
+ if (!((gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag) & r6))
+ {
+ STWI_send_SlotStatusREQ();
+ STWI_poll_CommandEnd();
+ r2 = gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data;
+ r3 = r2[1] - 1;
+ for (r2 += 8; r3 != 0; r2 += 4, --r3)
+ {
+ u16 r4 = *(u16 *)r2;
+
+ if (r2[2] == i && r4 == gRfuStatic->cidBak[i])
+ {
+ r9 |= 1 << i;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ connSlotFlag = gRfuLinkStatus->connSlotFlag;
+ r0 = *bmLinkLossSlot;
+ r0 &= connSlotFlag;
+ if (r6 & r0)
+ rfu_STC_removeLinkData(i, 0);
+ }
+ if (r9 != 0)
+ {
+ STWI_send_DisconnectREQ(r9);
+ STWI_poll_CommandEnd();
+ }
+ // equivalent to:
+ // gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket32.command = sp10;
+ *(u32 *)gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data = sp10;
+ gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket32.data[0] = sp14;
+ return 0;
+}
+
+static void rfu_STC_removeLinkData(u8 r7, u8 r12)
+{
+ u8 r5 = 1 << r7;
+ s32 r6;
+
+ if ((gRfuLinkStatus->connSlotFlag & r5) && gRfuLinkStatus->connCount != 0)
+ --gRfuLinkStatus->connCount;
+ gRfuLinkStatus->connSlotFlag &= r6 = ~r5;
+ gRfuLinkStatus->linkLossSlotFlag |= r5;
+ if ((*(u32 *)gRfuLinkStatus & 0xFF00FF) == 0)
+ gRfuLinkStatus->parentChild = MODE_NEUTRAL;
+ if (r12 != 0)
+ {
+ CpuFill16(0, &gRfuLinkStatus->partner[r7], sizeof(struct RfuTgtData));
+ gRfuLinkStatus->linkLossSlotFlag &= r6;
+ gRfuLinkStatus->getNameFlag &= r6;
+ gRfuLinkStatus->strength[r7] = 0;
+ }
+}
+
+void rfu_REQ_disconnect(u8 bmDisconnectSlot)
+{
+ u16 r1;
+
+ if ((gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag) & bmDisconnectSlot)
+ {
+ gRfuStatic->recoveryBmSlot = bmDisconnectSlot;
+ if (gRfuLinkStatus->parentChild == MODE_NEUTRAL && gRfuStatic->flags & 0x80)
+ {
+ if (gRfuLinkStatus->linkLossSlotFlag & bmDisconnectSlot)
+ rfu_CB_disconnect(48, 0);
+ }
+ else if (gRfuStatic->SCStartFlag
+ && (STWI_set_Callback_M(rfu_CB_defaultCallback),
+ STWI_send_SC_EndREQ(),
+ (r1 = STWI_poll_CommandEnd()) != 0))
+ {
+ rfu_STC_REQ_callback(27, r1);
+ }
+ else
+ {
+ STWI_set_Callback_M(rfu_CB_disconnect);
+ STWI_send_DisconnectREQ(bmDisconnectSlot);
+ }
+ }
+}
+
+static void rfu_CB_disconnect(u8 r6, u16 r5)
+{
+ u8 r4, r0;
+
+ if (r5 == 3 && gRfuLinkStatus->parentChild == MODE_CHILD)
+ {
+ STWI_set_Callback_M(rfu_CB_defaultCallback);
+ STWI_send_SystemStatusREQ();
+ if (STWI_poll_CommandEnd() == 0 && gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[7] == 0)
+ r5 = 0;
+ }
+ gRfuStatic->recoveryBmSlot &= gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag;
+ gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[8] = gRfuStatic->recoveryBmSlot;
+ if (r5 == 0)
+ {
+ for (r4 = 0; r4 < RFU_CHILD_MAX; ++r4)
+ {
+ r0 = 1 << r4;
+ if (r0 & gRfuStatic->recoveryBmSlot)
+ rfu_STC_removeLinkData(r4, 1);
+ }
+ }
+ if ((gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag) == 0)
+ gRfuLinkStatus->parentChild = MODE_NEUTRAL;
+ rfu_STC_REQ_callback(r6, r5);
+ if (gRfuStatic->SCStartFlag)
+ {
+ STWI_set_Callback_M(rfu_CB_defaultCallback);
+ STWI_send_SC_StartREQ();
+ r5 = STWI_poll_CommandEnd();
+ if (r5 != 0)
+ rfu_STC_REQ_callback(25, r5);
+ }
+}
+
+void rfu_REQ_CHILD_startConnectRecovery(u8 bmRecoverySlot)
+{
+ u8 i;
+
+ gRfuStatic->recoveryBmSlot = bmRecoverySlot;
+ for (i = 0; i < RFU_CHILD_MAX && !((bmRecoverySlot >> i) & 1); ++i)
+ ;
+ STWI_set_Callback_M(rfu_STC_REQ_callback);
+ // if i == 4, gRfuLinkStatus->partner[i].id becomes gRfuLinkStatus->my.id
+ STWI_send_CPR_StartREQ(gRfuLinkStatus->partner[i].id, gRfuLinkStatus->my.id, bmRecoverySlot);
+}
+
+void rfu_REQ_CHILD_pollConnectRecovery(void)
+{
+ STWI_set_Callback_M(rfu_CB_CHILD_pollConnectRecovery);
+ STWI_send_CPR_PollingREQ();
+}
+
+static void rfu_CB_CHILD_pollConnectRecovery(u8 r8, u16 r7)
+{
+ u8 r3, r4;
+ struct RfuLinkStatus *r2;
+
+ if (r7 == 0 && gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[4] == 0 && gRfuStatic->recoveryBmSlot)
+ {
+ gRfuLinkStatus->parentChild = MODE_CHILD;
+ for (r4 = 0; r4 < NELEMS(gRfuStatic->linkEmergencyFlag); ++r4)
+ {
+ r3 = 1 << r4;
+ r2 = gRfuLinkStatus; // ???
+ if (gRfuStatic->recoveryBmSlot & r3 & r2->linkLossSlotFlag)
+ {
+ gRfuLinkStatus->connSlotFlag |= r3;
+ gRfuLinkStatus->linkLossSlotFlag &= ~r3;
+ ++gRfuLinkStatus->connCount;
+ gRfuStatic->linkEmergencyFlag[r4] = 0;
+ }
+ }
+ gRfuStatic->recoveryBmSlot = 0;
+ }
+ rfu_STC_REQ_callback(r8, r7);
+}
+
+u16 rfu_CHILD_getConnectRecoveryStatus(u8 *status)
+{
+ u8 r0;
+
+ *status = 0xFF;
+ r0 = gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[0] + 77;
+ if (r0 <= 1)
+ {
+ *status = gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[4];
+ return 0;
+ }
+ return ERR_REQ_CMD_ID;
+}
+
+void rfu_REQ_CHILD_endConnectRecovery(void)
+{
+ STWI_set_Callback_M(rfu_CB_CHILD_pollConnectRecovery);
+ STWI_send_CPR_EndREQ();
+}
+
+static void rfu_STC_fastCopy(const u8 **src_p, u8 **dst_p, s32 size)
+{
+ const u8 *src = *src_p;
+ u8 *dst = *dst_p;
+ s32 i;
+
+ for (i = size - 1; i != -1; --i)
+ *dst++ = *src++;
+ *src_p = src;
+ *dst_p = dst;
+}
+
+void rfu_REQ_changeMasterSlave(void)
+{
+ if (STWI_read_status(1) == 1)
+ {
+ STWI_set_Callback_M(rfu_STC_REQ_callback);
+ STWI_send_MS_ChangeREQ();
+ }
+ else
+ {
+ rfu_STC_REQ_callback(39, 0);
+ }
+}
+
+bool8 rfu_getMasterSlave(void)
+{
+ bool8 masterSlave = STWI_read_status(1);
+
+ if (masterSlave == AGB_CLK_MASTER)
+ {
+ if (gSTWIStatus->unk_2c)
+ {
+ if (gSTWIStatus->reqActiveCommand == 39
+ || gSTWIStatus->reqActiveCommand == 37
+ || gSTWIStatus->reqActiveCommand == 55)
+ masterSlave = AGB_CLK_SLAVE;
+ }
+ }
+ return masterSlave;
+}
+
+void rfu_clearAllSlot(void)
+{
+ u16 i;
+ u16 IMEBackup = REG_IME;
+
+ REG_IME = 0;
+ for (i = 0; i < RFU_CHILD_MAX; ++i)
+ {
+ CpuFill16(0, gRfuSlotStatusNI[i], 2 * sizeof(struct NIComm));
+ CpuFill16(0, gRfuSlotStatusUNI[i], sizeof(struct UNISend) + sizeof(struct UNIRecv));
+ gRfuLinkStatus->remainLLFrameSizeChild[i] = 16;
+ }
+ gRfuLinkStatus->remainLLFrameSizeParent = LLF_P_SIZE;
+ gRfuLinkStatus->sendSlotNIFlag = 0;
+ gRfuLinkStatus->recvSlotNIFlag = 0;
+ gRfuLinkStatus->sendSlotUNIFlag = 0;
+ gRfuStatic->recvRenewalFlag = 0;
+ REG_IME = IMEBackup;
+}
+
+static void rfu_STC_releaseFrame(u8 r5, u8 r3, struct NIComm *r4)
+{
+
+ if (!(gRfuStatic->flags & 0x80))
+ {
+ if (r3 == 0)
+ gRfuLinkStatus->remainLLFrameSizeParent += r4->payloadSize;
+ gRfuLinkStatus->remainLLFrameSizeParent += 3;
+ }
+ else
+ {
+ if (r3 == 0)
+ gRfuLinkStatus->remainLLFrameSizeChild[r5] += r4->payloadSize;
+ gRfuLinkStatus->remainLLFrameSizeChild[r5] += 2;
+ }
+}
+
+u16 rfu_clearSlot(u8 connTypeFlag, u8 slotStatusIndex)
+{
+ u16 r10, r3, r1;
+ struct NIComm *r4;
+
+ if (slotStatusIndex >= RFU_CHILD_MAX)
+ return ERR_SLOT_NO;
+ if (!(connTypeFlag & (TYPE_UNI_SEND | TYPE_UNI_RECV | TYPE_NI_SEND | TYPE_NI_RECV)))
+ return ERR_COMM_TYPE;
+ r10 = REG_IME;
+ REG_IME = 0;
+ if (connTypeFlag & (TYPE_NI_SEND | TYPE_NI_RECV))
+ {
+ for (r3 = 0; r3 < 2; ++r3)
+ {
+ r4 = NULL;
+ if (r3 == 0)
+ {
+ if (connTypeFlag & TYPE_NI_SEND)
+ {
+ r4 = &gRfuSlotStatusNI[slotStatusIndex]->send;
+ gRfuLinkStatus->sendSlotNIFlag &= ~r4->bmSlotOrg;
+ }
+ }
+ else
+ {
+ if (connTypeFlag & TYPE_NI_RECV)
+ {
+ r4 = &gRfuSlotStatusNI[slotStatusIndex]->recv;
+ gRfuLinkStatus->recvSlotNIFlag &= ~(1 << slotStatusIndex);
+ }
+ }
+ if (r4 != NULL)
+ {
+ if (r4->state & SLOT_BUSY_FLAG)
+ {
+ rfu_STC_releaseFrame(slotStatusIndex, r3, r4);
+ for (r1 = 0; r1 < RFU_CHILD_MAX; ++r1)
+ if ((r4->bmSlotOrg >> r1) & 1)
+ r4->failCounter = 0;
+ }
+ CpuFill16(0, r4, sizeof(struct NIComm));
+ }
+ }
+ }
+ if (connTypeFlag & TYPE_UNI_SEND)
+ {
+ struct RfuSlotStatusUNI *r3 = gRfuSlotStatusUNI[slotStatusIndex];
+
+ if (r3->send.state & SLOT_BUSY_FLAG)
+ {
+ if (!(gRfuStatic->flags & 0x80))
+ gRfuLinkStatus->remainLLFrameSizeParent += 3 + (u8)r3->send.payloadSize;
+ else
+ gRfuLinkStatus->remainLLFrameSizeChild[slotStatusIndex] += 2 + (u8)r3->send.payloadSize;
+ gRfuLinkStatus->sendSlotUNIFlag &= ~r3->send.bmSlot;
+ }
+ CpuFill16(0, &r3->send, sizeof(struct UNISend));
+ }
+ if (connTypeFlag & TYPE_UNI_RECV)
+ {
+ CpuFill16(0, &gRfuSlotStatusUNI[slotStatusIndex]->recv, sizeof(struct UNIRecv));
+ }
+ REG_IME = r10;
+ return 0;
+}
+
+u16 rfu_setRecvBuffer(u8 connType, u8 slotNo, void *buffer, u32 buffSize)
+{
+ if (slotNo >= RFU_CHILD_MAX)
+ return ERR_SLOT_NO;
+ if (connType & TYPE_NI)
+ {
+ gRfuSlotStatusNI[slotNo]->recvBuffer = buffer;
+ gRfuSlotStatusNI[slotNo]->recvBufferSize = buffSize;
+ }
+ else if (!(connType & TYPE_UNI))
+ {
+ return ERR_COMM_TYPE;
+ }
+ else
+ {
+ gRfuSlotStatusUNI[slotNo]->recvBuffer = buffer;
+ gRfuSlotStatusUNI[slotNo]->recvBufferSize = buffSize;
+ }
+ return 0;
+}
+
+u16 rfu_NI_setSendData(u8 bmSendSlot, u8 subFrameSize, const void *src, u32 size)
+{
+ return rfu_STC_setSendData_org(32, bmSendSlot, subFrameSize, src, size);
+}
+
+u16 rfu_UNI_setSendData(u8 bmSendSlot, const void *src, u8 size)
+{
+ u8 subFrameSize;
+
+ if (gRfuLinkStatus->parentChild == MODE_PARENT)
+ subFrameSize = size + 3;
+ else
+ subFrameSize = size + 2;
+ return rfu_STC_setSendData_org(16, bmSendSlot, subFrameSize, src, 0);
+}
+
+u16 rfu_NI_CHILD_setSendGameName(u8 slotNo, u8 subFrameSize)
+{
+ return rfu_STC_setSendData_org(64, 1 << slotNo, subFrameSize, &gRfuLinkStatus->my.serialNo, 26);
+}
+
+static u16 rfu_STC_setSendData_org(u8 r6, u8 bmSendSlot, u8 subFrameSize, const void *src, u32 sp28)
+{
+ u8 r2, r0;
+ u8 r4;
+ u8 *r9;
+ u8 r5;
+ u8 i;
+ u16 sp04;
+ struct RfuSlotStatusUNI *r1;
+ struct RfuSlotStatusNI *r12;
+
+ if (gRfuLinkStatus->parentChild == MODE_NEUTRAL)
+ return ERR_MODE_NOT_CONNECTED;
+ if (!(bmSendSlot & 0xF))
+ return ERR_SLOT_NO;
+ if (((gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag) & bmSendSlot) != bmSendSlot)
+ return ERR_SLOT_NOT_CONNECTED;
+ if (r6 & 0x10)
+ r0 = gRfuLinkStatus->sendSlotUNIFlag;
+ else
+ r0 = gRfuLinkStatus->sendSlotNIFlag;
+ if (r0 & bmSendSlot)
+ return ERR_SLOT_BUSY;
+ for (r2 = 0; r2 < RFU_CHILD_MAX && !((bmSendSlot >> r2) & 1); ++r2)
+ ;
+ if (gRfuLinkStatus->parentChild == MODE_PARENT)
+ r9 = &gRfuLinkStatus->remainLLFrameSizeParent;
+ else if (gRfuLinkStatus->parentChild == MODE_CHILD)
+ r9 = &gRfuLinkStatus->remainLLFrameSizeChild[r2];
+ r4 = llsf_struct[gRfuLinkStatus->parentChild].unk00;
+ if (subFrameSize > *r9 || subFrameSize <= r4)
+ return ERR_SUBFRAME_SIZE;
+ sp04 = REG_IME;
+ REG_IME = 0;
+ r5 = r6 & 0x20;
+ if (r5 || r6 == 0x40)
+ {
+ u8 *r1; // a hack to swap instructions
+
+ r12 = gRfuSlotStatusNI[r2];
+ r1 = NULL;
+ r12->send.errorCode = 0;
+ *r12->send.now_p = r1 = &r12->send.dataType;
+ r12->send.remainSize = 7;
+ r12->send.bmSlotOrg = bmSendSlot;
+ r12->send.bmSlot = bmSendSlot;
+ r12->send.payloadSize = subFrameSize - r4;
+ if (r5 != 0)
+ *r1 = 0;
+ else
+ *r1 = 1;
+ r12->send.dataSize = sp28;
+ r12->send.src = src;
+ r12->send.ack = 0;
+ r12->send.phase = 0;
+ #ifndef NONMATCHING // to fix r2, r3, r4, r5 register roulette
+ asm("":::"r2");
+ #endif
+ for (i = 0; i < WINDOW_COUNT; ++i)
+ {
+ r12->send.recvAckFlag[i] = 0;
+ r12->send.n[i] = 1;
+ }
+ for (r2 = 0; r2 < RFU_CHILD_MAX; ++r2)
+ if ((bmSendSlot >> r2) & 1)
+ gRfuSlotStatusNI[r2]->send.failCounter = 0;
+ gRfuLinkStatus->sendSlotNIFlag |= bmSendSlot;
+ *r9 -= subFrameSize;
+ r12->send.state = SLOT_STATE_SEND_START;
+ }
+ else if (r6 & 0x10)
+ {
+ r1 = gRfuSlotStatusUNI[r2];
+ r1->send.bmSlot = bmSendSlot;
+ r1->send.src = src;
+ r1->send.payloadSize = subFrameSize - r4;
+ *r9 -= subFrameSize;
+ r1->send.state = SLOT_STATE_SEND_UNI;
+ gRfuLinkStatus->sendSlotUNIFlag |= bmSendSlot;
+ }
+ REG_IME = sp04;
+ return 0;
+}
+
+u16 rfu_changeSendTarget(u8 connType, u8 slotStatusIndex, u8 bmNewTgtSlot)
+{
+ struct RfuSlotStatusNI *r5;
+ u16 r8;
+ u8 r2;
+
+ if (slotStatusIndex >= RFU_CHILD_MAX)
+ return ERR_SLOT_NO;
+ if (connType == 0x20)
+ {
+ r5 = gRfuSlotStatusNI[slotStatusIndex];
+ if ((r5->send.state & SLOT_BUSY_FLAG)
+ && (r5->send.state & SLOT_SEND_FLAG))
+ {
+ connType = bmNewTgtSlot ^ r5->send.bmSlot;
+
+ if (!(connType & bmNewTgtSlot))
+ {
+ if (connType)
+ {
+ r8 = REG_IME;
+ REG_IME = 0;
+ for (r2 = 0; r2 < RFU_CHILD_MAX; ++r2)
+ {
+ if ((connType >> r2) & 1)
+ gRfuSlotStatusNI[r2]->send.failCounter = 0;
+ }
+ gRfuLinkStatus->sendSlotNIFlag &= ~connType;
+ r5->send.bmSlot = bmNewTgtSlot;
+ if (r5->send.bmSlot == 0)
+ {
+ rfu_STC_releaseFrame(slotStatusIndex, 0, &r5->send);
+ r5->send.state = SLOT_STATE_SEND_FAILED;
+ }
+ REG_IME = r8;
+ }
+ }
+ else
+ {
+ return ERR_SLOT_TARGET;
+ }
+ }
+ else
+ {
+ return ERR_SLOT_NOT_SENDING;
+ }
+ }
+ else
+ {
+ if (connType == 16)
+ {
+ s32 r3;
+
+ if (gRfuSlotStatusUNI[slotStatusIndex]->send.state != SLOT_STATE_SEND_UNI)
+ return ERR_SLOT_NOT_SENDING;
+ for (r3 = 0, r2 = 0; r2 < RFU_CHILD_MAX; ++r2)
+ if (r2 != slotStatusIndex)
+ r3 |= gRfuSlotStatusUNI[r2]->send.bmSlot;
+ if (bmNewTgtSlot & r3)
+ return ERR_SLOT_TARGET;
+ r8 = REG_IME;
+ REG_IME = 0;
+ gRfuLinkStatus->sendSlotUNIFlag &= ~gRfuSlotStatusUNI[slotStatusIndex]->send.bmSlot;
+ gRfuLinkStatus->sendSlotUNIFlag |= bmNewTgtSlot;
+ gRfuSlotStatusUNI[slotStatusIndex]->send.bmSlot = bmNewTgtSlot;
+ REG_IME = r8;
+ }
+ else
+ {
+ return ERR_COMM_TYPE;
+ }
+ }
+ return 0;
+}
+
+u16 rfu_NI_stopReceivingData(u8 slotStatusIndex)
+{
+ struct NIComm *r5;
+ u16 r4, r1;
+
+ if (slotStatusIndex >= RFU_CHILD_MAX)
+ return ERR_SLOT_NO;
+ r5 = &gRfuSlotStatusNI[slotStatusIndex]->recv;
+ r4 = REG_IME;
+ ++r4; --r4; // fix r4, r5 register swap
+ REG_IME = 0;
+ if (gRfuSlotStatusNI[slotStatusIndex]->recv.state & SLOT_BUSY_FLAG)
+ {
+ if (gRfuSlotStatusNI[slotStatusIndex]->recv.state == SLOT_STATE_RECV_LAST)
+ gRfuSlotStatusNI[slotStatusIndex]->recv.state = SLOT_STATE_RECV_SUCCESS_AND_SENDSIDE_UNKNOWN;
+ else
+ gRfuSlotStatusNI[slotStatusIndex]->recv.state = SLOT_STATE_RECV_FAILED;
+ gRfuLinkStatus->recvSlotNIFlag &= ~(1 << slotStatusIndex);
+ rfu_STC_releaseFrame(slotStatusIndex, 1, r5);
+ }
+ REG_IME = r4;
+ return 0;
+}
+
+u16 rfu_UNI_changeAndReadySendData(u8 slotStatusIndex, const void *src, u8 size)
+{
+ struct UNISend *r4;
+ u8 *r6;
+ u16 r1;
+ u8 r3_;
+
+ if (slotStatusIndex >= RFU_CHILD_MAX)
+ return ERR_SLOT_NO;
+ r4 = &gRfuSlotStatusUNI[slotStatusIndex]->send;
+ if (r4->state != SLOT_STATE_SEND_UNI)
+ return ERR_SLOT_NOT_SENDING;
+ if (gRfuLinkStatus->parentChild == MODE_PARENT)
+ {
+ r6 = &gRfuLinkStatus->remainLLFrameSizeParent;
+ r3_ = gRfuLinkStatus->remainLLFrameSizeParent + (u8)r4->payloadSize;
+ }
+ else
+ {
+ r6 = &gRfuLinkStatus->remainLLFrameSizeChild[slotStatusIndex];
+ r3_ = gRfuLinkStatus->remainLLFrameSizeChild[slotStatusIndex] + (u8)r4->payloadSize;
+ }
+ if (r3_ < size)
+ return ERR_SUBFRAME_SIZE;
+ r1 = REG_IME;
+ REG_IME = 0;
+ r4->src = src;
+ *r6 = r3_ - size;
+ r4->payloadSize = size;
+ r4->dataReadyFlag = 1;
+ REG_IME = r1;
+ return 0;
+}
+
+void rfu_UNI_readySendData(u8 slotStatusIndex)
+{
+ if (slotStatusIndex < RFU_CHILD_MAX)
+ {
+ if (gRfuSlotStatusUNI[slotStatusIndex]->send.state == SLOT_STATE_SEND_UNI)
+ gRfuSlotStatusUNI[slotStatusIndex]->send.dataReadyFlag = 1;
+ }
+}
+
+void rfu_UNI_clearRecvNewDataFlag(u8 slotStatusIndex)
+{
+ if (slotStatusIndex < RFU_CHILD_MAX)
+ gRfuSlotStatusUNI[slotStatusIndex]->recv.newDataFlag = 0;
+}
+
+void rfu_REQ_sendData(u8 clockChangeFlag)
+{
+ if (gRfuLinkStatus->parentChild != MODE_NEUTRAL)
+ {
+ if (gRfuLinkStatus->parentChild == 1
+ && !(gRfuLinkStatus->sendSlotNIFlag | gRfuLinkStatus->recvSlotNIFlag | gRfuLinkStatus->sendSlotUNIFlag))
+ {
+ if (gRfuStatic->commExistFlag)
+ {
+ gRfuStatic->emberCount = 16;
+ gRfuStatic->nullFrameCount = 0;
+ }
+ if (gRfuStatic->emberCount)
+ --gRfuStatic->emberCount;
+ else
+ ++gRfuStatic->nullFrameCount;
+ if (gRfuStatic->emberCount
+ || !(gRfuStatic->nullFrameCount & 0xF))
+ {
+ gRfuFixed->LLFBuffer[0] = 1;
+ gRfuFixed->LLFBuffer[4] = 0xFF;
+ STWI_set_Callback_M(rfu_CB_sendData3);
+ if (clockChangeFlag == 0)
+ STWI_send_DataTxREQ(gRfuFixed->LLFBuffer, 1);
+ else
+ STWI_send_DataTxAndChangeREQ(gRfuFixed->LLFBuffer, 1);
+ return;
+ }
+ }
+ else
+ {
+ if (!gRfuLinkStatus->LLFReadyFlag)
+ rfu_constructSendLLFrame();
+ if (gRfuLinkStatus->LLFReadyFlag)
+ {
+ STWI_set_Callback_M(rfu_CB_sendData);
+ if (clockChangeFlag != 0)
+ {
+ STWI_send_DataTxAndChangeREQ(gRfuFixed->LLFBuffer, gRfuStatic->totalPacketSize + 4);
+ return;
+ }
+ STWI_send_DataTxREQ(gRfuFixed->LLFBuffer, gRfuStatic->totalPacketSize + 4);
+ }
+ }
+ if (clockChangeFlag != 0)
+ {
+ if (gRfuLinkStatus->parentChild == MODE_PARENT)
+ {
+ if (gSTWIStatus->callbackS != NULL)
+ gSTWIStatus->callbackS(39);
+ }
+ else
+ {
+ STWI_set_Callback_M(rfu_CB_sendData2);
+ STWI_send_MS_ChangeREQ();
+ }
+ }
+ }
+}
+
+static void rfu_CB_sendData(UNUSED u8 r0, u16 r7)
+{
+ u8 r6;
+ struct NIComm *r4;
+
+ if (r7 == 0)
+ {
+ for (r6 = 0; r6 < RFU_CHILD_MAX; ++r6)
+ {
+ if (gRfuSlotStatusUNI[r6]->send.dataReadyFlag)
+ gRfuSlotStatusUNI[r6]->send.dataReadyFlag = 0;
+ r4 = &gRfuSlotStatusNI[r6]->send;
+ if (r4->state == SLOT_STATE_SEND_NULL)
+ {
+ rfu_STC_releaseFrame(r6, 0, r4);
+ gRfuLinkStatus->sendSlotNIFlag &= ~r4->bmSlot;
+ if (r4->dataType == 1)
+ gRfuLinkStatus->getNameFlag |= 1 << r6;
+ r4->state = SLOT_STATE_SEND_SUCCESS;
+ }
+ }
+ }
+ gRfuLinkStatus->LLFReadyFlag = 0;
+ rfu_STC_REQ_callback(36, r7);
+}
+
+static void rfu_CB_sendData2(UNUSED u8 r0, u16 r1)
+{
+ rfu_STC_REQ_callback(36, r1);
+}
+
+static void rfu_CB_sendData3(u8 r0, u16 r1)
+{
+ if (r1 != 0)
+ rfu_STC_REQ_callback(36, r1);
+ else if (r0 == 0xFF)
+ rfu_STC_REQ_callback(0xFF, 0);
+}
+
+static void rfu_constructSendLLFrame(void)
+{
+ u32 r8, r5;
+ u8 r6;
+ u8 *sp00;
+ struct RfuSlotStatusNI *r2;
+
+ if (gRfuLinkStatus->parentChild != MODE_NEUTRAL
+ && gRfuLinkStatus->sendSlotNIFlag | gRfuLinkStatus->recvSlotNIFlag | gRfuLinkStatus->sendSlotUNIFlag)
+ {
+ gRfuLinkStatus->LLFReadyFlag = 0;
+ r8 = 0;
+ sp00 = (u8 *)&gRfuFixed->LLFBuffer[1];
+ for (r6 = 0; r6 < RFU_CHILD_MAX; ++r6)
+ {
+ r5 = 0;
+ if (gRfuSlotStatusNI[r6]->send.state & SLOT_BUSY_FLAG)
+ r5 = rfu_STC_NI_constructLLSF(r6, &sp00, &gRfuSlotStatusNI[r6]->send);
+ if (gRfuSlotStatusNI[r6]->recv.state & SLOT_BUSY_FLAG)
+ r5 += rfu_STC_NI_constructLLSF(r6, &sp00, &gRfuSlotStatusNI[r6]->recv);
+ if (gRfuSlotStatusUNI[r6]->send.state == SLOT_STATE_SEND_UNI)
+ r5 += rfu_STC_UNI_constructLLSF(r6, &sp00);
+ if (r5 != 0)
+ {
+ if (gRfuLinkStatus->parentChild == MODE_PARENT)
+ r8 += r5;
+ else
+ r8 |= r5 << (5 * r6 + 8);
+ }
+ }
+ if (r8 != 0)
+ {
+ while ((u32)sp00 & 3)
+ *sp00++ = 0;
+ gRfuFixed->LLFBuffer[0] = r8;
+ if (gRfuLinkStatus->parentChild == MODE_CHILD)
+ {
+ u8 *r0 = sp00 - offsetof(struct RfuFixed, LLFBuffer[1]);
+
+ // Does the volatile qualifier make sense?
+ // It's the same as:
+ // asm("":::"memory");
+ r8 = r0 - *(u8 *volatile *)&gRfuFixed;
+ }
+ }
+ gRfuStatic->totalPacketSize = r8;
+ }
+}
+
+static u16 rfu_STC_NI_constructLLSF(u8 r10, u8 **r12, struct NIComm *r4)
+{
+ u16 r5;
+ u32 sp00;
+ u8 i;
+ u8 *r2;
+ const struct LLSFStruct *r8 = &llsf_struct[gRfuLinkStatus->parentChild];
+
+ if (r4->state == SLOT_STATE_SENDING)
+ {
+ while (r4->now_p[r4->phase] >= (const u8 *)r4->src + r4->dataSize)
+ {
+ ++r4->phase;
+ if (r4->phase == 4)
+ r4->phase = 0;
+ }
+ }
+ if (r4->state & SLOT_RECV_FLAG)
+ {
+ r5 = 0;
+ }
+ else if (r4->state == SLOT_STATE_SENDING)
+ {
+ if (r4->now_p[r4->phase] + r4->payloadSize > (const u8 *)r4->src + r4->dataSize)
+ r5 = (const u8 *)r4->src + r4->dataSize - r4->now_p[r4->phase];
+ else
+ r5 = r4->payloadSize;
+ }
+ else
+ {
+ if ((u32)r4->remainSize >= r4->payloadSize)
+ r5 = r4->payloadSize;
+ else
+ r5 = r4->remainSize;
+ }
+ sp00 = (r4->state & 0xF) << r8->unk03
+ | r4->ack << r8->unk04
+ | r4->phase << r8->unk05
+ | r4->n[r4->phase] << r8->unk06
+ | r5;
+ if (gRfuLinkStatus->parentChild == MODE_PARENT)
+ sp00 |= r4->bmSlot << 18;
+ r2 = (u8 *)&sp00;
+ for (i = 0; i < r8->unk00; ++i)
+ *(*r12)++ = *r2++;
+ if (r5 != 0)
+ {
+ const u8 *sp04 = r4->now_p[r4->phase];
+
+ gRfuFixed->fastCopyPtr(&sp04, r12, r5);
+ }
+ if (r4->state == SLOT_STATE_SENDING)
+ {
+ ++r4->phase;
+ if (r4->phase == 4)
+ r4->phase = 0;
+ }
+ if (gRfuLinkStatus->parentChild == MODE_PARENT)
+ gRfuLinkStatus->LLFReadyFlag = 1;
+ else
+ gRfuLinkStatus->LLFReadyFlag |= 1 << r10;
+ return r5 + r8->unk00;
+}
+
+static u16 rfu_STC_UNI_constructLLSF(u8 r8, u8 **r6)
+{
+ const struct LLSFStruct *r5;
+ const u8 *sp04;
+ u32 sp00;
+ u8 *r2;
+ u8 i;
+ struct UNISend *r4 = &gRfuSlotStatusUNI[r8]->send;
+
+ if (!r4->dataReadyFlag || !r4->bmSlot)
+ return 0;
+ r5 = &llsf_struct[gRfuLinkStatus->parentChild];
+ sp00 = (r4->state & 0xF) << r5->unk03
+ | r4->payloadSize;
+ if (gRfuLinkStatus->parentChild == MODE_PARENT)
+ sp00 |= r4->bmSlot << 18;
+ r2 = (u8 *)&sp00;
+ for (i = 0; i < r5->unk00; ++i)
+ *(*r6)++ = *r2++;
+ sp04 = r4->src;
+ gRfuFixed->fastCopyPtr(&sp04, r6, r4->payloadSize);
+ if (gRfuLinkStatus->parentChild == MODE_PARENT)
+ gRfuLinkStatus->LLFReadyFlag = 16;
+ else
+ gRfuLinkStatus->LLFReadyFlag |= 16 << r8;
+ return r5->unk00 + r4->payloadSize;
+}
+
+void rfu_REQ_recvData(void)
+{
+ if (gRfuLinkStatus->parentChild != MODE_NEUTRAL)
+ {
+ gRfuStatic->commExistFlag = gRfuLinkStatus->sendSlotNIFlag | gRfuLinkStatus->recvSlotNIFlag | gRfuLinkStatus->sendSlotUNIFlag;
+ gRfuStatic->recvErrorFlag = 0;
+ STWI_set_Callback_M(rfu_CB_recvData);
+ STWI_send_DataRxREQ();
+ }
+}
+
+static void rfu_CB_recvData(u8 r9, u16 r7)
+{
+ u8 r6;
+ struct RfuSlotStatusNI *r4;
+ struct NIComm *r5;
+
+ if (r7 == 0 && gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[1])
+ {
+ gRfuStatic->NIEndRecvFlag = 0;
+ if (gRfuLinkStatus->parentChild == MODE_PARENT)
+ rfu_STC_PARENT_analyzeRecvPacket();
+ else
+ rfu_STC_CHILD_analyzeRecvPacket();
+ for (r6 = 0; r6 < RFU_CHILD_MAX; ++r6)
+ {
+ r4 = gRfuSlotStatusNI[r6];
+ if (r4->recv.state == SLOT_STATE_RECV_LAST && !((gRfuStatic->NIEndRecvFlag >> r6) & 1))
+ {
+ r5 = &r4->recv;
+ if (r5->dataType == 1)
+ gRfuLinkStatus->getNameFlag |= 1 << r6;
+ rfu_STC_releaseFrame(r6, 1, r5);
+ gRfuLinkStatus->recvSlotNIFlag &= ~r5->bmSlot;
+ r4->recv.state = SLOT_STATE_RECV_SUCCESS;
+ }
+ }
+ if (gRfuStatic->recvErrorFlag)
+ r7 = gRfuStatic->recvErrorFlag | ERR_DATA_RECV;
+ }
+ rfu_STC_REQ_callback(r9, r7);
+}
+
+static void rfu_STC_PARENT_analyzeRecvPacket(void)
+{
+ u32 r3;
+ u8 r5;
+ u8 sp[4];
+ u8 *r6;
+
+ r3 = gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket32.data[0] >> 8;
+ for (r5 = 0; r5 < NELEMS(sp); ++r5)
+ {
+ sp[r5] = r3 & 0x1F;
+ r3 >>= 5;
+ if (sp[r5] == 0)
+ gRfuStatic->NIEndRecvFlag |= 1 << r5;
+ }
+ r6 = &gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[8];
+ for (r5 = 0; r5 < NELEMS(sp); ++r5)
+ {
+ if (sp[r5])
+ {
+ u8 *r4 = &sp[r5];
+
+ do
+ {
+ u8 r0 = rfu_STC_analyzeLLSF(r5, r6, *r4);
+
+ r6 += r0;
+ *r4 -= r0;
+ } while (!(*r4 & 0x80) && (*r4));
+ }
+ }
+}
+
+static void rfu_STC_CHILD_analyzeRecvPacket(void)
+{
+ u16 r4;
+ u8 *r5;
+ u16 r0;
+
+ r4 = *(u16 *)&gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[4] & 0x7F;
+ r5 = &gRfuFixed->STWIBuffer->rxPacketAlloc.rfuPacket8.data[8];
+ if (r4 == 0)
+ gRfuStatic->NIEndRecvFlag = 15;
+ do
+ {
+ if (r4 == 0)
+ break;
+ r0 = rfu_STC_analyzeLLSF(0, r5, r4);
+ r5 += r0;
+ r4 -= r0;
+ } while (!(r4 & 0x8000));
+}
+
+static u16 rfu_STC_analyzeLLSF(u8 r12, const u8 *r7, u16 r3)
+{
+ struct RfuLocalStruct sp00;
+ const struct LLSFStruct *r6;
+ u32 r5;
+ u8 r4;
+ u32 r0;
+ u16 r10;
+
+ r6 = &llsf_struct[~gRfuLinkStatus->parentChild & (MODE_NEUTRAL & MODE_PARENT)];
+ if (r3 < r6->unk00)
+ return r3;
+ r5 = 0;
+ for (r4 = 0; r4 < r6->unk00; ++r4)
+ r5 |= *r7++ << 8 * r4;
+ sp00.unk00 = (r5 >> r6->unk01) & r6->unk07;
+ sp00.unk01 = (r5 >> r6->unk02) & r6->unk08;
+ sp00.unk02 = (r5 >> r6->unk03) & r6->unk09;
+ sp00.unk03 = (r5 >> r6->unk04) & r6->unk0A;
+ sp00.unk04 = (r5 >> r6->unk05) & r6->unk0B;
+ sp00.unk05 = (r5 >> r6->unk06) & r6->unk0C;
+ sp00.unk06 = (r5 & r6->unk0E) & r5;
+ r10 = sp00.unk06 + r6->unk00;
+ if (sp00.unk00 == 0)
+ {
+ if (gRfuLinkStatus->parentChild == MODE_PARENT)
+ {
+ if ((gRfuLinkStatus->connSlotFlag >> r12) & 1)
+ {
+ if (sp00.unk02 == 4)
+ {
+ rfu_STC_UNI_receive(r12, &sp00, r7);
+ }
+ else if (sp00.unk03 == 0)
+ {
+ rfu_STC_NI_receive_Receiver(r12, &sp00, r7);
+ }
+ else
+ {
+ for (r4 = 0; r4 < RFU_CHILD_MAX; ++r4)
+ if (((gRfuSlotStatusNI[r4]->send.bmSlot >> r12) & 1)
+ && ((gRfuLinkStatus->sendSlotNIFlag >> r12) & 1))
+ break;
+ if (r4 <= 3)
+ rfu_STC_NI_receive_Sender(r4, r12, &sp00, r7);
+ }
+ }
+ }
+ else
+ {
+ s32 r5 = gRfuLinkStatus->connSlotFlag & sp00.unk01;
+
+ if (r5)
+ {
+ for (r4 = 0; r4 < RFU_CHILD_MAX; ++r4)
+ {
+ if ((r5 >> r4) & 1)
+ {
+ if (sp00.unk02 == 4)
+ rfu_STC_UNI_receive(r4, &sp00, r7);
+ else if (sp00.unk03 == 0)
+ rfu_STC_NI_receive_Receiver(r4, &sp00, r7);
+ else if ((gRfuLinkStatus->sendSlotNIFlag >> r4) & 1)
+ rfu_STC_NI_receive_Sender(r4, r4, &sp00, r7);
+ }
+ }
+ }
+ }
+ }
+ return r10;
+}
+
+static void rfu_STC_UNI_receive(u8 r7, const struct RfuLocalStruct *r6, const u8 *sp00)
+{
+ u8 *sp04;
+ u32 r2;
+ struct RfuSlotStatusUNI *r3 = gRfuSlotStatusUNI[r7];
+ struct UNIRecv *r5 = &r3->recv;
+
+ r5->errorCode = 0;
+ if (gRfuSlotStatusUNI[r7]->recvBufferSize < r6->unk06)
+ {
+ r3->recv.state = SLOT_STATE_RECV_IGNORE;
+ r5->errorCode = ERR_RECV_BUFF_OVER;
+ }
+ else
+ {
+ if (r5->dataBlockFlag)
+ {
+ if (r5->newDataFlag)
+ {
+ r5->errorCode = ERR_RECV_UNK;
+ goto _081E2F0E;
+ }
+ }
+ else
+ {
+ if (r5->newDataFlag)
+ r5->errorCode = ERR_RECV_DATA_OVERWRITED;
+ }
+ r5->state = SLOT_STATE_RECEIVING;
+ r2 = r5->dataSize = r6->unk06;
+ sp04 = gRfuSlotStatusUNI[r7]->recvBuffer;
+ gRfuFixed->fastCopyPtr(&sp00, &sp04, r2);
+ r5->newDataFlag = 1;
+ r5->state = 0;
+ }
+_081E2F0E:
+ if (r5->errorCode)
+ gRfuStatic->recvErrorFlag |= 16 << r7;
+}
+
+static void rfu_STC_NI_receive_Sender(u8 r0, u8 r10, const struct RfuLocalStruct *r6, const u8 *r3)
+{
+ struct NIComm *r12 = &gRfuSlotStatusNI[r0]->send;
+ u16 r9 = r12->state;
+ u8 sp00 = r12->n[r6->unk04];
+ u8 *r8;
+ u8 r4;
+ u16 r2;
+
+ if ((r6->unk02 == 2 && r9 == SLOT_STATE_SENDING)
+ || (r6->unk02 == 1 && r9 == SLOT_STATE_SEND_START)
+ || (r6->unk02 == 3 && r9 == SLOT_STATE_SEND_LAST))
+ {
+ if (r12->n[r6->unk04] == r6->unk05)
+ r12->recvAckFlag[r6->unk04] |= 1 << r10;
+ }
+ if ((r12->recvAckFlag[r6->unk04] & r12->bmSlot) == r12->bmSlot)
+ {
+ r12->n[r6->unk04] = (r12->n[r6->unk04] + 1) & 3;
+ r12->recvAckFlag[r6->unk04] = 0;
+ if ((u16)(r12->state + ~SLOT_STATE_SEND_NULL) <= 1)
+ {
+ if (r12->state == SLOT_STATE_SEND_START)
+ r12->now_p[r6->unk04] += r12->payloadSize;
+ else
+ r12->now_p[r6->unk04] += r12->payloadSize << 2;
+ r12->remainSize -= r12->payloadSize;
+ if (r12->remainSize != 0)
+ if (r12->remainSize >= 0)
+ goto _081E30AE;
+ // Above is a hack to avoid optimization over comparison.
+ // rfu_STC_NI_constructLLSF uses this field as u32.
+ // It's equivalent to the following condition:
+ // if (r12->remainSize == 0 || r12->remainSize < 0)
+ {
+ r12->phase = 0;
+ if (r12->state == SLOT_STATE_SEND_START)
+ {
+ for (r4 = 0; r4 < WINDOW_COUNT; ++r4)
+ {
+ r12->n[r4] = 1;
+ r12->now_p[r4] = r12->src + r12->payloadSize * r4;
+ }
+ r12->remainSize = r12->dataSize;
+ r12->state = SLOT_STATE_SENDING;
+ }
+ else
+ {
+ r12->n[0] = 0;
+ r12->remainSize = 0;
+ r12->state = SLOT_STATE_SEND_LAST;
+ }
+ }
+ _081E30AE:
+ }
+ else if (r12->state == SLOT_STATE_SEND_LAST)
+ {
+ r12->state = SLOT_STATE_SEND_NULL;
+ }
+ }
+ if (r12->state != r9
+ || r12->n[r6->unk04] != sp00
+ || (r12->recvAckFlag[r6->unk04] >> r10) & 1)
+ {
+ r2 = REG_IME;
+ REG_IME = 0;
+ gRfuStatic->recvRenewalFlag |= 16 << r10;
+ gRfuSlotStatusNI[r10]->send.failCounter = 0;
+ REG_IME = r2;
+ }
+}
+
+static void rfu_STC_NI_receive_Receiver(u8 r8, const struct RfuLocalStruct *r6, const u8 *sp00)
+{
+ u16 r2;
+ u32 r7 = 0;
+ struct RfuSlotStatusNI *r4 = gRfuSlotStatusNI[r8];
+ struct NIComm *r5 = &r4->recv;
+ u16 r9 = r4->recv.state;
+ u8 r10 = r4->recv.n[r6->unk04];
+
+ if (r6->unk02 == 3)
+ {
+ gRfuStatic->NIEndRecvFlag |= 1 << r8;
+ if (r4->recv.state == SLOT_STATE_RECEIVING)
+ {
+ r4->recv.phase = 0;
+ r4->recv.n[0] = 0;
+ r4->recv.state = SLOT_STATE_RECV_LAST;
+ }
+ }
+ else if (r6->unk02 == 2)
+ {
+ if (r9 == SLOT_STATE_RECV_START && !r5->remainSize)
+ rfu_STC_NI_initSlot_asRecvDataEntity(r8, r5);
+ if (r5->state == SLOT_STATE_RECEIVING)
+ r7 = 1;
+ }
+ else if (r6->unk02 == 1)
+ {
+ if (r9 == SLOT_STATE_RECV_START)
+ {
+ r7 = 1;
+ }
+ else
+ {
+ rfu_STC_NI_initSlot_asRecvControllData(r8, r5);
+ if (r4->recv.state != SLOT_STATE_RECV_START)
+ return;
+ r7 = 1;
+ }
+ }
+ if (r7 != 0)
+ {
+ if (r6->unk05 == ((r5->n[r6->unk04] + 1) & 3))
+ {
+ gRfuFixed->fastCopyPtr(&sp00, (u8 **)&r5->now_p[r6->unk04], r6->unk06);
+ if (r5->state == SLOT_STATE_RECEIVING)
+ r5->now_p[r6->unk04] += 3 * r5->payloadSize;
+ r5->remainSize -= r6->unk06;
+ r5->n[r6->unk04] = r6->unk05;
+ }
+ }
+ if (r5->errorCode == 0)
+ {
+ r5->phase = r6->unk04;
+ if (r5->state != r9 || r5->n[r6->unk04] != r10 || r5->n[r6->unk04] == r6->unk05)
+ {
+ r2 = REG_IME;
+ REG_IME = 0;
+ gRfuStatic->recvRenewalFlag |= 1 << r8;
+ r5->failCounter = 0;
+ REG_IME = r2;
+ }
+ }
+}
+
+static void rfu_STC_NI_initSlot_asRecvControllData(u8 r4, struct NIComm *r2)
+{
+ u8 *r1;
+ u32 r5;
+ u8 r6;
+
+ if (gRfuLinkStatus->parentChild == MODE_PARENT)
+ {
+ r5 = 3;
+ r1 = &gRfuLinkStatus->remainLLFrameSizeParent;
+ }
+ else
+ {
+ r5 = 2;
+ r1 = &gRfuLinkStatus->remainLLFrameSizeChild[r4];
+ }
+ r6 = 1 << r4;
+ if (r2->state == 0)
+ {
+ if (*r1 < r5)
+ {
+ r2->state = SLOT_STATE_RECV_IGNORE;
+ r2->errorCode = ERR_RECV_REPLY_SUBFRAME_SIZE;
+ gRfuStatic->recvErrorFlag |= r6;
+ }
+ else
+ {
+ r2->errorCode = 0;
+ *r1 -= r5;
+ r2->now_p[0] = &r2->dataType;
+ r2->remainSize = 7;
+ r2->ack = 1;
+ r2->payloadSize = 0;
+ r2->bmSlot = r6;
+ r2->state = SLOT_STATE_RECV_START;
+ gRfuLinkStatus->recvSlotNIFlag |= r6;
+ }
+ }
+}
+
+static void rfu_STC_NI_initSlot_asRecvDataEntity(u8 r5, struct NIComm *r4)
+{
+ u8 r1, r3;
+
+ if (r4->dataType == 1)
+ {
+ r4->now_p[0] = (void *)&gRfuLinkStatus->partner[r5].serialNo;
+ }
+ else
+ {
+ if (r4->dataSize > gRfuSlotStatusNI[r5]->recvBufferSize)
+ {
+ r1 = 1 << r5;
+ gRfuStatic->recvErrorFlag |= r1;
+ gRfuLinkStatus->recvSlotNIFlag &= ~r1;
+ r4->errorCode = ERR_RECV_BUFF_OVER;
+ r4->state = SLOT_STATE_RECV_FAILED;
+ rfu_STC_releaseFrame(r5, 1, r4);
+ return;
+ }
+ r4->now_p[0] = gRfuSlotStatusNI[r5]->recvBuffer;
+ }
+ for (r3 = 0; r3 < WINDOW_COUNT; ++r3)
+ {
+ r4->n[r3] = 0;
+ r4->now_p[r3] = &r4->now_p[0][r4->payloadSize * r3];
+ }
+ r4->remainSize = r4->dataSize;
+ r4->state = SLOT_STATE_RECEIVING;
+}
+
+static void rfu_NI_checkCommFailCounter(void)
+{
+ u16 r12;
+ u32 r7;
+ u8 r2, r3;
+
+ if (gRfuLinkStatus->sendSlotNIFlag | gRfuLinkStatus->recvSlotNIFlag)
+ {
+ r12 = REG_IME;
+ REG_IME = 0;
+ r7 = gRfuStatic->recvRenewalFlag >> 4;
+ for (r3 = 0; r3 < RFU_CHILD_MAX; ++r3)
+ {
+ r2 = 1 << r3;
+ if (gRfuLinkStatus->sendSlotNIFlag & r2
+ && !(gRfuStatic->recvRenewalFlag & r2))
+ ++gRfuSlotStatusNI[r3]->send.failCounter;
+ if (gRfuLinkStatus->recvSlotNIFlag & r2
+ && !(r7 & r2))
+ ++gRfuSlotStatusNI[r3]->recv.failCounter;
+ }
+ gRfuStatic->recvRenewalFlag = 0;
+ REG_IME = r12;
+ }
+}
+
+void rfu_REQ_noise(void)
+{
+ STWI_set_Callback_M(rfu_STC_REQ_callback);
+ STWI_send_TestModeREQ(1, 0);
+}
diff --git a/src/librfu_sio32id.c b/src/librfu_sio32id.c
new file mode 100644
index 000000000..fc5701986
--- /dev/null
+++ b/src/librfu_sio32id.c
@@ -0,0 +1,164 @@
+#include "librfu.h"
+
+static void Sio32IDIntr(void);
+static void Sio32IDInit(void);
+static s32 Sio32IDMain(void);
+
+struct RfuSIO32Id gRfuSIO32Id;
+
+static const u16 Sio32ConnectionData[] = { 0x494e, 0x544e, 0x4e45, 0x4f44 }; // NINTENDO
+static const char Sio32IDLib_Var[] = "Sio32ID_030820";
+
+s32 AgbRFU_checkID(u8 r5)
+{
+ u16 r8;
+ vu16 *r4;
+ s32 r6;
+
+ if (REG_IME == 0)
+ return -1;
+ r8 = REG_IE;
+ gSTWIStatus->state = 10;
+ STWI_set_Callback_ID(Sio32IDIntr);
+ Sio32IDInit();
+ r4 = &REG_TMCNT_L(gSTWIStatus->timerSelect);
+ r5 *= 8;
+ while (--r5 != 0xFF)
+ {
+ r6 = Sio32IDMain();
+ if (r6 != 0)
+ break;
+ r4[1] = 0;
+ r4[0] = 0;
+ r4[1] = TIMER_1024CLK | TIMER_ENABLE;
+ while (r4[0] < 32)
+ ;
+ r4[1] = 0;
+ r4[0] = 0;
+ }
+ REG_IME = 0;
+ REG_IE = r8;
+ REG_IME = 1;
+ gSTWIStatus->state = 0;
+ STWI_set_Callback_ID(NULL);
+ return r6;
+}
+
+static void Sio32IDInit(void)
+{
+ REG_IME = 0;
+ REG_IE &= ~((8 << gSTWIStatus->timerSelect) | INTR_FLAG_SERIAL);
+ REG_IME = 1;
+ REG_RCNT = 0;
+ REG_SIOCNT = SIO_32BIT_MODE;
+ REG_SIOCNT |= SIO_INTR_ENABLE | SIO_ENABLE;
+ CpuFill32(0, &gRfuSIO32Id, sizeof(struct RfuSIO32Id));
+ REG_IF = INTR_FLAG_SERIAL;
+}
+
+static s32 Sio32IDMain(void)
+{
+ u8 r12;
+
+ switch (r12 = gRfuSIO32Id.unk1)
+ {
+ case 0:
+ gRfuSIO32Id.unk0 = 1;
+ REG_SIOCNT |= SIO_38400_BPS;
+ REG_IME = r12;
+ REG_IE |= INTR_FLAG_SERIAL;
+ REG_IME = 1;
+ gRfuSIO32Id.unk1 = 1;
+ *(vu8 *)&REG_SIOCNT |= SIO_ENABLE;
+ break;
+ case 1:
+ if (gRfuSIO32Id.unkA == 0)
+ {
+ if (gRfuSIO32Id.unk0 == 1)
+ {
+ if (gRfuSIO32Id.unk2 == 0)
+ {
+ REG_IME = gRfuSIO32Id.unk2;
+ REG_SIOCNT |= SIO_ENABLE;
+ REG_IME = r12;
+ }
+ }
+ else if (gRfuSIO32Id.unk4 != 0x8001 && !gRfuSIO32Id.unk2)
+ {
+ REG_IME = gRfuSIO32Id.unk2;
+ REG_IE &= ~INTR_FLAG_SERIAL;
+ REG_IME = r12;
+ REG_SIOCNT = gRfuSIO32Id.unk2;
+ REG_SIOCNT = SIO_32BIT_MODE;
+ REG_IF = INTR_FLAG_SERIAL;
+ REG_SIOCNT |= SIO_INTR_ENABLE | SIO_ENABLE;
+ REG_IME = gRfuSIO32Id.unk2;
+ REG_IE |= INTR_FLAG_SERIAL;
+ REG_IME = r12;
+ }
+ break;
+ }
+ else
+ {
+ gRfuSIO32Id.unk1 = 2;
+ // fallthrough
+ }
+ default:
+ return gRfuSIO32Id.unkA;
+ }
+ return 0;
+}
+
+static void Sio32IDIntr(void)
+{
+ u32 r5;
+ u16 r0;
+#ifndef NONMATCHING
+ register u32 r1 asm("r1");
+ register u16 r0_ asm("r0");
+#else
+ u32 r1;
+ u16 r0_;
+#endif
+
+ r5 = REG_SIODATA32;
+ if (gRfuSIO32Id.unk0 != 1)
+ REG_SIOCNT |= SIO_ENABLE;
+ r1 = 16 * gRfuSIO32Id.unk0; // to handle side effect of inline asm
+ r1 = (r5 << r1) >> 16;
+ r5 = (r5 << 16 * (1 - gRfuSIO32Id.unk0)) >> 16;
+ if (gRfuSIO32Id.unkA == 0)
+ {
+ if (r1 == gRfuSIO32Id.unk6)
+ {
+ if (gRfuSIO32Id.unk2 > 3)
+ {
+ gRfuSIO32Id.unkA = r5;
+ }
+ else if (r1 == (u16)~gRfuSIO32Id.unk4)
+ {
+ r0_ = ~gRfuSIO32Id.unk6;
+ if (r5 == r0_)
+ ++gRfuSIO32Id.unk2;
+ }
+ }
+ else
+ {
+ gRfuSIO32Id.unk2 = gRfuSIO32Id.unkA;
+ }
+ }
+ if (gRfuSIO32Id.unk2 < 4)
+ gRfuSIO32Id.unk4 = *(gRfuSIO32Id.unk2 + Sio32ConnectionData);
+ else
+ gRfuSIO32Id.unk4 = 0x8001;
+ gRfuSIO32Id.unk6 = ~r5;
+ REG_SIODATA32 = (gRfuSIO32Id.unk4 << 16 * (1 - gRfuSIO32Id.unk0))
+ + (gRfuSIO32Id.unk6 << 16 * gRfuSIO32Id.unk0);
+ if (gRfuSIO32Id.unk0 == 1 && (gRfuSIO32Id.unk2 || r5 == 0x494E))
+ {
+ for (r0 = 0; r0 < 600; ++r0)
+ ;
+ if (gRfuSIO32Id.unkA == 0)
+ REG_SIOCNT |= SIO_ENABLE;
+ }
+}
diff --git a/src/librfu_stwi.c b/src/librfu_stwi.c
new file mode 100644
index 000000000..b88f21737
--- /dev/null
+++ b/src/librfu_stwi.c
@@ -0,0 +1,647 @@
+#include "librfu.h"
+
+static void STWI_intr_timer(void);
+static u16 STWI_init(u8 request);
+static s32 STWI_start_Command(void);
+static void STWI_set_timer(u8 unk);
+static void STWI_stop_timer(void);
+static s32 STWI_restart_Command(void);
+static s32 STWI_reset_ClockCounter(void);
+
+struct STWIStatus *gSTWIStatus;
+
+void STWI_init_all(struct RfuIntrStruct *interruptStruct, IntrFunc *interrupt, bool8 copyInterruptToRam)
+{
+ // If we're copying our interrupt into RAM, DMA it to block1 and use
+ // block2 for our STWIStatus, otherwise block1 holds the STWIStatus.
+ // interrupt usually is a pointer to gIntrTable[1]
+ if (copyInterruptToRam == TRUE)
+ {
+ *interrupt = (IntrFunc)interruptStruct->block1;
+ DmaCopy16(3, &IntrSIO32, interruptStruct->block1, sizeof(interruptStruct->block1));
+ gSTWIStatus = &interruptStruct->block2;
+ }
+ else
+ {
+ *interrupt = IntrSIO32;
+ gSTWIStatus = (struct STWIStatus *)interruptStruct->block1;
+ }
+ gSTWIStatus->rxPacket = &interruptStruct->rxPacketAlloc;
+ gSTWIStatus->txPacket = &interruptStruct->txPacketAlloc;
+ gSTWIStatus->msMode = 1;
+ gSTWIStatus->state = 0;
+ gSTWIStatus->reqLength = 0;
+ gSTWIStatus->reqNext = 0;
+ gSTWIStatus->ackLength = 0;
+ gSTWIStatus->ackNext = 0;
+ gSTWIStatus->ackActiveCommand = 0;
+ gSTWIStatus->timerState = 0;
+ gSTWIStatus->timerActive = 0;
+ gSTWIStatus->error = 0;
+ gSTWIStatus->recoveryCount = 0;
+ gSTWIStatus->unk_2c = 0;
+ REG_RCNT = 0x100; // TODO: mystery bit?
+ REG_SIOCNT = SIO_INTR_ENABLE | SIO_32BIT_MODE | SIO_115200_BPS;
+ STWI_init_Callback_M();
+ STWI_init_Callback_S();
+ IntrEnable(INTR_FLAG_SERIAL);
+}
+
+void STWI_init_timer(IntrFunc *interrupt, s32 timerSelect)
+{
+ *interrupt = STWI_intr_timer;
+ gSTWIStatus->timerSelect = timerSelect;
+ IntrEnable(INTR_FLAG_TIMER0 << gSTWIStatus->timerSelect);
+}
+
+void AgbRFU_SoftReset(void)
+{
+ vu16 *timerL;
+ vu16 *timerH;
+
+ REG_RCNT = 0x8000;
+ REG_RCNT = 0x80A0; // all these bits are undocumented
+ timerL = &REG_TMCNT_L(gSTWIStatus->timerSelect);
+ timerH = &REG_TMCNT_H(gSTWIStatus->timerSelect);
+ *timerH = 0;
+ *timerL = 0;
+ *timerH = TIMER_ENABLE | TIMER_1024CLK;
+ while (*timerL <= 0x11)
+ REG_RCNT = 0x80A2;
+ *timerH = 3;
+ REG_RCNT = 0x80A0;
+ REG_SIOCNT = SIO_INTR_ENABLE | SIO_32BIT_MODE | SIO_115200_BPS;
+ gSTWIStatus->state = 0;
+ gSTWIStatus->reqLength = 0;
+ gSTWIStatus->reqNext = 0;
+ gSTWIStatus->reqActiveCommand = 0;
+ gSTWIStatus->ackLength = 0;
+ gSTWIStatus->ackNext = 0;
+ gSTWIStatus->ackActiveCommand = 0;
+ gSTWIStatus->timerState = 0;
+ gSTWIStatus->timerActive = 0;
+ gSTWIStatus->error = 0;
+ gSTWIStatus->msMode = 1;
+ gSTWIStatus->recoveryCount = 0;
+ gSTWIStatus->unk_2c = 0;
+}
+
+void STWI_set_MS_mode(u8 mode)
+{
+ gSTWIStatus->msMode = mode;
+}
+
+u16 STWI_read_status(u8 index)
+{
+ switch (index)
+ {
+ case 0:
+ return gSTWIStatus->error;
+ case 1:
+ return gSTWIStatus->msMode;
+ case 2:
+ return gSTWIStatus->state;
+ case 3:
+ return gSTWIStatus->reqActiveCommand;
+ default:
+ return 0xFFFF;
+ }
+}
+
+void STWI_init_Callback_M(void)
+{
+ STWI_set_Callback_M(NULL);
+}
+
+void STWI_init_Callback_S(void)
+{
+ STWI_set_Callback_S(NULL);
+}
+
+// The callback can take 2 or 3 arguments.
+void STWI_set_Callback_M(void *callbackM)
+{
+ gSTWIStatus->callbackM = callbackM;
+}
+
+void STWI_set_Callback_S(void (*callbackS)(u16))
+{
+ gSTWIStatus->callbackS = callbackS;
+}
+
+void STWI_set_Callback_ID(void (*func)(void)) // name in SDK, but is actually setting a function pointer
+{
+ gSTWIStatus->unk_20 = func;
+}
+
+u16 STWI_poll_CommandEnd(void)
+{
+ while (gSTWIStatus->unk_2c == TRUE)
+ ;
+ return gSTWIStatus->error;
+}
+
+void STWI_send_ResetREQ(void)
+{
+ if (!STWI_init(ID_RESET_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_LinkStatusREQ(void)
+{
+ if (!STWI_init(ID_LINK_STATUS_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_VersionStatusREQ(void)
+{
+ if (!STWI_init(ID_VERSION_STATUS_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_SystemStatusREQ(void)
+{
+ if (!STWI_init(ID_SYSTEM_STATUS_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_SlotStatusREQ(void)
+{
+ if (!STWI_init(ID_SLOT_STATUS_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_ConfigStatusREQ(void)
+{
+ if (!STWI_init(ID_CONFIG_STATUS_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_GameConfigREQ(const u8 *unk1, const u8 *data)
+{
+ u8 *packetBytes;
+ s32 i;
+
+ if (!STWI_init(ID_GAME_CONFIG_REQ))
+ {
+ gSTWIStatus->reqLength = 6;
+ // TODO: what is unk1
+ packetBytes = gSTWIStatus->txPacket->rfuPacket8.data;
+ packetBytes += sizeof(u32);
+ *(u16 *)packetBytes = *(u16 *)unk1;
+ packetBytes += sizeof(u16);
+ unk1 += sizeof(u16);
+ for (i = 0; i < 14; ++i)
+ {
+ *packetBytes = *unk1;
+ ++packetBytes;
+ ++unk1;
+ }
+ for (i = 0; i < 8; ++i)
+ {
+ *packetBytes = *data;
+ ++packetBytes;
+ ++data;
+ }
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_SystemConfigREQ(u16 unk1, u8 unk2, u8 unk3)
+{
+ if (!STWI_init(ID_SYSTEM_CONFIG_REQ))
+ {
+ u8 *packetBytes;
+
+ gSTWIStatus->reqLength = 1;
+ packetBytes = gSTWIStatus->txPacket->rfuPacket8.data;
+ packetBytes += sizeof(u32);
+ *packetBytes++ = unk3;
+ *packetBytes++ = unk2;
+ *(u16*)packetBytes = unk1;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_SC_StartREQ(void)
+{
+ if (!STWI_init(ID_SC_START_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_SC_PollingREQ(void)
+{
+ if (!STWI_init(ID_SC_POLL_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_SC_EndREQ(void)
+{
+ if (!STWI_init(ID_SC_END_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_SP_StartREQ(void)
+{
+ if (!STWI_init(ID_SP_START_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_SP_PollingREQ(void)
+{
+ if (!STWI_init(ID_SP_POLL_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_SP_EndREQ(void)
+{
+ if (!STWI_init(ID_SP_END_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_CP_StartREQ(u16 unk1)
+{
+ if (!STWI_init(ID_CP_START_REQ))
+ {
+ gSTWIStatus->reqLength = 1;
+ gSTWIStatus->txPacket->rfuPacket32.data[0] = unk1;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_CP_PollingREQ(void)
+{
+ if (!STWI_init(ID_CP_POLL_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_CP_EndREQ(void)
+{
+ if (!STWI_init(ID_CP_END_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_DataTxREQ(const void *in, u8 size)
+{
+ if (!STWI_init(ID_DATA_TX_REQ))
+ {
+ u8 reqLength = (size / sizeof(u32));
+ if (size & (sizeof(u32) - 1))
+ reqLength += 1;
+ gSTWIStatus->reqLength = reqLength;
+ CpuCopy32(in, gSTWIStatus->txPacket->rfuPacket32.data, gSTWIStatus->reqLength * sizeof(u32));
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_DataTxAndChangeREQ(const void *in, u8 size)
+{
+ if (!STWI_init(ID_DATA_TX_AND_CHANGE_REQ))
+ {
+ u8 reqLength = (size / sizeof(u32));
+ if (size & (sizeof(u32) - 1))
+ reqLength += 1;
+ gSTWIStatus->reqLength = reqLength;
+ CpuCopy32(in, gSTWIStatus->txPacket->rfuPacket32.data, gSTWIStatus->reqLength * sizeof(u32));
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_DataRxREQ(void)
+{
+ if (!STWI_init(ID_DATA_RX_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_MS_ChangeREQ(void)
+{
+ if (!STWI_init(ID_MS_CHANGE_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_DataReadyAndChangeREQ(u8 unk)
+{
+ if (!STWI_init(ID_DATA_READY_AND_CHANGE_REQ))
+ {
+ if (!unk)
+ {
+ gSTWIStatus->reqLength = 0;
+ }
+ else
+ {
+ u8 *packetBytes;
+
+ gSTWIStatus->reqLength = 1;
+ packetBytes = gSTWIStatus->txPacket->rfuPacket8.data;
+ packetBytes += sizeof(u32);
+ *packetBytes++ = unk;
+ *packetBytes++ = 0;
+ *packetBytes++ = 0;
+ *packetBytes = 0;
+ }
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_DisconnectedAndChangeREQ(u8 unk0, u8 unk1)
+{
+ if (!STWI_init(ID_DISCONNECTED_AND_CHANGE_REQ))
+ {
+ u8 *packetBytes;
+
+ gSTWIStatus->reqLength = 1;
+ packetBytes = gSTWIStatus->txPacket->rfuPacket8.data;
+ packetBytes += sizeof(u32);
+ *packetBytes++ = unk0;
+ *packetBytes++ = unk1;
+ *packetBytes++ = 0;
+ *packetBytes = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_ResumeRetransmitAndChangeREQ(void)
+{
+ if (!STWI_init(ID_RESUME_RETRANSMIT_AND_CHANGE_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_DisconnectREQ(u8 unk)
+{
+ if (!STWI_init(ID_DISCONNECT_REQ))
+ {
+ gSTWIStatus->reqLength = 1;
+ gSTWIStatus->txPacket->rfuPacket32.data[0] = unk;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_TestModeREQ(u8 unk0, u8 unk1)
+{
+ if (!STWI_init(ID_TEST_MODE_REQ))
+ {
+ gSTWIStatus->reqLength = 1;
+ gSTWIStatus->txPacket->rfuPacket32.data[0] = unk0 | (unk1 << 8);
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_CPR_StartREQ(u16 unk0, u16 unk1, u8 unk2)
+{
+ u32 *packetData;
+ u32 arg1;
+
+ if (!STWI_init(ID_CPR_START_REQ))
+ {
+ gSTWIStatus->reqLength = 2;
+ arg1 = unk1 | (unk0 << 16);
+ packetData = gSTWIStatus->txPacket->rfuPacket32.data;
+ packetData[0] = arg1;
+ packetData[1] = unk2;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_CPR_PollingREQ(void)
+{
+ if (!STWI_init(ID_CPR_POLL_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_CPR_EndREQ(void)
+{
+ if (!STWI_init(ID_CPR_END_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+void STWI_send_StopModeREQ(void)
+{
+ if (!STWI_init(ID_STOP_MODE_REQ))
+ {
+ gSTWIStatus->reqLength = 0;
+ STWI_start_Command();
+ }
+}
+
+static void STWI_intr_timer(void)
+{
+ switch (gSTWIStatus->timerState)
+ {
+ // TODO: Make an enum for these
+ case 2:
+ gSTWIStatus->timerActive = 1;
+ STWI_set_timer(50);
+ break;
+ case 1:
+ case 4:
+ STWI_stop_timer();
+ STWI_restart_Command();
+ break;
+ case 3:
+ gSTWIStatus->timerActive = 1;
+ STWI_stop_timer();
+ STWI_reset_ClockCounter();
+ if (gSTWIStatus->callbackM != NULL)
+ gSTWIStatus->callbackM(255, 0);
+ break;
+ }
+}
+
+static void STWI_set_timer(u8 unk)
+{
+ vu16 *timerL;
+ vu16 *timerH;
+
+ timerL = &REG_TMCNT_L(gSTWIStatus->timerSelect);
+ timerH = &REG_TMCNT_H(gSTWIStatus->timerSelect);
+ REG_IME = 0;
+ switch (unk)
+ {
+ case 50:
+ *timerL = 0xFCCB;
+ gSTWIStatus->timerState = 1;
+ break;
+ case 80:
+ *timerL = 0xFAE0;
+ gSTWIStatus->timerState = 2;
+ break;
+ case 100:
+ *timerL = 0xF996;
+ gSTWIStatus->timerState = 3;
+ break;
+ case 130:
+ *timerL = 0xF7AD;
+ gSTWIStatus->timerState = 4;
+ break;
+ }
+ *timerH = TIMER_ENABLE | TIMER_INTR_ENABLE | TIMER_1024CLK;
+ REG_IF = INTR_FLAG_TIMER0 << gSTWIStatus->timerSelect;
+ REG_IME = 1;
+}
+
+static void STWI_stop_timer(void)
+{
+ gSTWIStatus->timerState = 0;
+ REG_TMCNT_L(gSTWIStatus->timerSelect) = 0;
+ REG_TMCNT_H(gSTWIStatus->timerSelect) = 0;
+}
+
+static u16 STWI_init(u8 request)
+{
+ if (!REG_IME)
+ {
+ gSTWIStatus->error = ERR_REQ_CMD_IME_DISABLE;
+ if (gSTWIStatus->callbackM != NULL)
+ gSTWIStatus->callbackM(request, gSTWIStatus->error);
+ return TRUE;
+ }
+ else if (gSTWIStatus->unk_2c == TRUE)
+ {
+ gSTWIStatus->error = ERR_REQ_CMD_SENDING;
+ gSTWIStatus->unk_2c = FALSE;
+ if (gSTWIStatus->callbackM != NULL)
+ gSTWIStatus->callbackM(request, gSTWIStatus->error);
+ return TRUE;
+ }
+ else if(!gSTWIStatus->msMode)
+ {
+ gSTWIStatus->error = ERR_REQ_CMD_CLOCK_SLAVE;
+ if (gSTWIStatus->callbackM != NULL)
+ gSTWIStatus->callbackM(request, gSTWIStatus->error, gSTWIStatus);
+ return TRUE;
+ }
+ else
+ {
+ gSTWIStatus->unk_2c = TRUE;
+ gSTWIStatus->reqActiveCommand = request;
+ gSTWIStatus->state = 0;
+ gSTWIStatus->reqLength = 0;
+ gSTWIStatus->reqNext = 0;
+ gSTWIStatus->ackLength = 0;
+ gSTWIStatus->ackNext = 0;
+ gSTWIStatus->ackActiveCommand = 0;
+ gSTWIStatus->timerState = 0;
+ gSTWIStatus->timerActive = 0;
+ gSTWIStatus->error = 0;
+ gSTWIStatus->recoveryCount = 0;
+ REG_RCNT = 0x100;
+ REG_SIOCNT = SIO_INTR_ENABLE | SIO_32BIT_MODE | SIO_115200_BPS;
+ return FALSE;
+ }
+}
+
+static s32 STWI_start_Command(void)
+{
+ u16 imeTemp;
+
+ // equivalent to gSTWIStatus->txPacket->rfuPacket32.command,
+ // but the cast here is required to avoid register issue
+ *(u32 *)gSTWIStatus->txPacket->rfuPacket8.data = 0x99660000 | (gSTWIStatus->reqLength << 8) | gSTWIStatus->reqActiveCommand;
+ REG_SIODATA32 = gSTWIStatus->txPacket->rfuPacket32.command;
+ gSTWIStatus->state = 0;
+ gSTWIStatus->reqNext = 1;
+ imeTemp = REG_IME;
+ REG_IME = 0;
+ REG_IE |= (INTR_FLAG_TIMER0 << gSTWIStatus->timerSelect);
+ REG_IE |= INTR_FLAG_SERIAL;
+ REG_IME = imeTemp;
+ REG_SIOCNT = SIO_INTR_ENABLE | SIO_32BIT_MODE | SIO_MULTI_BUSY | SIO_115200_BPS;
+ return 0;
+}
+
+static s32 STWI_restart_Command(void)
+{
+ if (gSTWIStatus->recoveryCount <= 1)
+ {
+ ++gSTWIStatus->recoveryCount;
+ STWI_start_Command();
+ }
+ else
+ {
+ if (gSTWIStatus->reqActiveCommand == ID_MS_CHANGE_REQ || gSTWIStatus->reqActiveCommand == ID_DATA_TX_AND_CHANGE_REQ || gSTWIStatus->reqActiveCommand == ID_UNK35_REQ || gSTWIStatus->reqActiveCommand == ID_RESUME_RETRANSMIT_AND_CHANGE_REQ)
+ {
+ gSTWIStatus->error = ERR_REQ_CMD_CLOCK_DRIFT;
+ gSTWIStatus->unk_2c = 0;
+ if (gSTWIStatus->callbackM != NULL)
+ gSTWIStatus->callbackM(gSTWIStatus->reqActiveCommand, gSTWIStatus->error);
+ }
+ else
+ {
+ gSTWIStatus->error = ERR_REQ_CMD_CLOCK_DRIFT;
+ gSTWIStatus->unk_2c = 0;
+ if (gSTWIStatus->callbackM != NULL)
+ gSTWIStatus->callbackM(gSTWIStatus->reqActiveCommand, gSTWIStatus->error);
+ gSTWIStatus->state = 4; // TODO: what's 4
+ }
+ }
+ return 0;
+}
+
+static s32 STWI_reset_ClockCounter(void)
+{
+ gSTWIStatus->state = 5; // TODO: what is 5
+ gSTWIStatus->reqLength = 0;
+ gSTWIStatus->reqNext = 0;
+ REG_SIODATA32 = (1 << 31);
+ REG_SIOCNT = 0;
+ REG_SIOCNT = SIO_INTR_ENABLE | SIO_32BIT_MODE | SIO_115200_BPS;
+ REG_SIOCNT = (SIO_INTR_ENABLE | SIO_32BIT_MODE | SIO_115200_BPS) + 0x7F;
+ return 0;
+}
diff --git a/src/main.c b/src/main.c
index c96e4cc3a..5d2db95be 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,4 +1,9 @@
#include "global.h"
+#include "bg.h"
+#include "gpu_regs.h"
+#include "link.h"
+#include "link_rfu.h"
+#include "load_save.h"
#include "main.h"
#include "m4a.h"
#include "random.h"
@@ -6,48 +11,20 @@
#include "gba/flash_internal.h"
#include "battle.h"
#include "help_system.h"
+#include "sound.h"
+#include "new_menu_helpers.h"
+#include "malloc.h"
+#include "overworld.h"
+#include "sprite.h"
+#include "play_time.h"
+#include "pokemon.h"
+#include "intro.h"
+#include "battle_controllers.h"
+#include "scanline_effect.h"
+#include "save_failed_screen.h"
+#include "battle.h"
-extern u16 GetGpuReg(u8);
-extern void SetGpuReg(u8, u16);
-extern void RFUVSync(void);
-extern void LinkVSync(void);
-extern void sub_80FCF34(void);
-extern void LinkVSync(void);
-extern void InitGpuRegManager(void);
-extern void InitRFU(void);
-extern void CheckForFlashMemory(void);
-extern void InitMapMusic(void);
-extern void ResetBgs(void);
-extern void SetDefaultFontsPointer(void);
-extern void InitHeap(void *heapStart, u32 heapSize); // malloc.h
-extern void rfu_REQ_stopMode(void);
-extern void rfu_waitREQComplete(void);
-extern bool32 sub_80582E0(void);
-extern bool32 sub_8058274(void);
-extern void ClearSpriteCopyRequests(void);
-extern void PlayTimeCounter_Update(void);
-extern void MapMusicMain(void);
-extern void EnableInterrupts(u16);
-extern void sub_800DD28(void);
-extern u16 SetFlashTimerIntr(u8 timerNum, void (**intrFunc)(void));
-extern void ScanlineEffect_Stop(void);
-extern void sub_80F50F4(void);
-extern bool32 sub_80F5118(void);
-
-extern struct SoundInfo gSoundInfo;
-extern u32 gFlashMemoryPresent;
-extern u32 IntrMain[];
-extern u8 gHeap[];
-extern struct SaveBlock1 gSaveBlock1;
-extern struct SaveBlock2 gSaveBlock2;
-extern struct PokemonStorage gPokemonStorage;
-extern u32 gBattleTypeFlags;
-extern u8 gUnknown_03002748;
-extern u32 *gUnknown_0203CF5C;
-
-void Timer3Intr(void);
-bool8 HandleLinkConnection(void);
-void c2_copyright_1(void);
+extern u32 intr_main[];
static void VBlankIntr(void);
static void HBlankIntr(void);
@@ -313,7 +290,7 @@ void InitIntrHandlers(void)
for (i = 0; i < INTR_COUNT; i++)
gIntrTable[i] = gIntrTableTemplate[i];
- DmaCopy32(3, IntrMain, IntrMain_Buffer, sizeof(IntrMain_Buffer));
+ DmaCopy32(3, intr_main, IntrMain_Buffer, sizeof(IntrMain_Buffer));
INTR_VECTOR = IntrMain_Buffer;
diff --git a/src/map_preview_screen.c b/src/map_preview_screen.c
index 0747e8ade..c5b41a7c1 100644
--- a/src/map_preview_screen.c
+++ b/src/map_preview_screen.c
@@ -552,7 +552,7 @@ static void sub_80F83D0(u8 taskId)
}
}
-const struct MapPreviewScreen * sub_80F8544(u8 mapsec)
+const struct MapPreviewScreen * GetDungeonMapPreviewScreenInfo(u8 mapsec)
{
u8 idx;
diff --git a/src/party_menu.c b/src/party_menu.c
index 399794b2d..6e0b411bf 100644
--- a/src/party_menu.c
+++ b/src/party_menu.c
@@ -4201,7 +4201,7 @@ static void sub_8124BB0(struct Pokemon *mon, u8 fieldMove)
Free(ptr);
}
-void sub_8124C1C(const u8 *healLocCtrlData) // TODO: confirm the type of data chunk at 0x83F2EE0
+void sub_8124C1C(const u8 *healLocCtrlData)
{
const struct MapHeader *mapHeader;
struct FieldMoveWarpParams *ptr2;
diff --git a/src/party_menu_specials.c b/src/party_menu_specials.c
new file mode 100644
index 000000000..751684bd5
--- /dev/null
+++ b/src/party_menu_specials.c
@@ -0,0 +1,111 @@
+#include "global.h"
+#include "data.h"
+#include "script.h"
+#include "overworld.h"
+#include "battle.h"
+#include "palette.h"
+#include "pokemon.h"
+#include "party_menu.h"
+#include "field_fadetransition.h"
+#include "pokemon_summary_screen.h"
+#include "event_data.h"
+#include "string_util.h"
+#include "constants/moves.h"
+
+static void sub_80BF97C(u8 taskId);
+
+void Special_ChooseMonFromParty(void)
+{
+ u8 taskId;
+
+ ScriptContext2_Enable();
+ taskId = CreateTask(sub_80BF97C, 10);
+ gTasks[taskId].data[0] = PARTY_MENU_TYPE_CHOOSE_MON;
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
+}
+
+void Special_SelectMoveTutorMon(void)
+{
+ u8 taskId;
+
+ ScriptContext2_Enable();
+ taskId = CreateTask(sub_80BF97C, 10);
+ gTasks[taskId].data[0] = PARTY_MENU_TYPE_MOVE_RELEARNER;
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
+}
+
+static void sub_80BF97C(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ gPaletteFade.bufferTransferDisabled = TRUE;
+ ChoosePartyMonByMenuType((u8)gTasks[taskId].data[0]);
+ DestroyTask(taskId);
+ }
+}
+
+void Special_SelectMove(void)
+{
+ ShowSelectMovePokemonSummaryScreen(gPlayerParty, gSpecialVar_0x8004, gPlayerPartyCount - 1, CB2_ReturnToField, 0);
+ sub_8138B38(3);
+ gFieldCallback = FieldCallback_ReturnToEventScript2;
+}
+
+void Special_GetNumMovesSelectedMonHas(void)
+{
+ u8 i;
+
+ gSpecialVar_Result = 0;
+ for (i = 0; i < MAX_MON_MOVES; ++i)
+ if (GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_MOVE1 + i) != MOVE_NONE)
+ ++gSpecialVar_Result;
+}
+
+void Special_BufferMoveDeleterNicknameAndMove(void)
+{
+ struct Pokemon *mon = &gPlayerParty[gSpecialVar_0x8004];
+ u16 move = GetMonData(mon, MON_DATA_MOVE1 + gSpecialVar_0x8005);
+
+ GetMonNickname(mon, gStringVar1);
+ StringCopy(gStringVar2, gMoveNames[move]);
+}
+
+static void ShiftMoveSlot(struct Pokemon *mon, u8 slotTo, u8 slotFrom)
+{
+ u16 move1 = GetMonData(mon, MON_DATA_MOVE1 + slotTo);
+ u16 move0 = GetMonData(mon, MON_DATA_MOVE1 + slotFrom);
+ u8 pp1 = GetMonData(mon, MON_DATA_PP1 + slotTo);
+ u8 pp0 = GetMonData(mon, MON_DATA_PP1 + slotFrom);
+ u8 ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES);
+ u8 ppBonusMask1 = gPPUpGetMask[slotTo];
+ u8 ppBonusMove1 = (ppBonuses & ppBonusMask1) >> (slotTo * 2);
+ u8 ppBonusMask2 = gPPUpGetMask[slotFrom];
+ u8 ppBonusMove2 = (ppBonuses & ppBonusMask2) >> (slotFrom * 2);
+
+ ppBonuses &= ~ppBonusMask1;
+ ppBonuses &= ~ppBonusMask2;
+ ppBonuses |= (ppBonusMove1 << (slotFrom * 2)) + (ppBonusMove2 << (slotTo * 2));
+ SetMonData(mon, MON_DATA_MOVE1 + slotTo, &move0);
+ SetMonData(mon, MON_DATA_MOVE1 + slotFrom, &move1);
+ SetMonData(mon, MON_DATA_PP1 + slotTo, &pp0);
+ SetMonData(mon, MON_DATA_PP1 + slotFrom, &pp1);
+ SetMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses);
+}
+
+void Special_MoveDeleterForgetMove(void)
+{
+ u16 i;
+
+ SetMonMoveSlot(&gPlayerParty[gSpecialVar_0x8004], MOVE_NONE, gSpecialVar_0x8005);
+ RemoveMonPPBonus(&gPlayerParty[gSpecialVar_0x8004], gSpecialVar_0x8005);
+ for (i = gSpecialVar_0x8005; i < MAX_MON_MOVES - 1; ++i)
+ ShiftMoveSlot(&gPlayerParty[gSpecialVar_0x8004], i, i + 1);
+}
+
+void Special_IsSelectedMonEgg(void)
+{
+ if (GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_IS_EGG))
+ gSpecialVar_Result = TRUE;
+ else
+ gSpecialVar_Result = FALSE;
+}
diff --git a/src/pc_screen_effect.c b/src/pc_screen_effect.c
new file mode 100644
index 000000000..5cc09df71
--- /dev/null
+++ b/src/pc_screen_effect.c
@@ -0,0 +1,156 @@
+#include "global.h"
+#include "task.h"
+#include "gpu_regs.h"
+#include "palette.h"
+
+static void sub_80A0AC0(TaskFunc func, u16 a2, UNUSED u16 a3, u8 priority);
+static void sub_80A0B0C(u8 taskId);
+static void sub_80A0C78(u8 taskId);
+
+void sub_80A0A48(u16 a1, u16 a2, u8 a3)
+{
+ sub_80A0AC0(sub_80A0B0C, a1, a2, a3);
+}
+
+void sub_80A0A70(u16 a1, u16 a2, u8 a3)
+{
+ sub_80A0AC0(sub_80A0C78, a1, a2, a3);
+}
+
+bool8 sub_80A0A98(void)
+{
+ return FuncIsActiveTask(sub_80A0B0C);
+}
+
+bool8 sub_80A0AAC(void)
+{
+ return FuncIsActiveTask(sub_80A0C78);
+}
+
+static void sub_80A0AC0(TaskFunc func, u16 a2, UNUSED u16 a3, u8 priority)
+{
+ u8 taskId = CreateTask(func, priority);
+
+ gTasks[taskId].data[0] = 0;
+ gTasks[taskId].data[1] = a2 == 0 ? 16 : a2;
+ gTasks[taskId].data[2] = a2 == 0 ? 20 : a2;
+ gTasks[taskId].func(taskId);
+}
+
+static void sub_80A0B0C(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ task->data[3] = 120;
+ task->data[4] = 120;
+ task->data[5] = 80;
+ task->data[6] = 81;
+ SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON);
+ SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(task->data[3], task->data[4]));
+ SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(task->data[5], task->data[6]));
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR);
+ SetGpuReg(REG_OFFSET_WINOUT, 0);
+ break;
+ case 1:
+ task->data[7] = GetGpuReg(REG_OFFSET_BLDCNT);
+ task->data[8] = GetGpuReg(REG_OFFSET_BLDY);
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_LIGHTEN);
+ SetGpuReg(REG_OFFSET_BLDY, 16);
+ break;
+ case 2:
+ task->data[3] -= task->data[1];
+ task->data[4] += task->data[1];
+ if (task->data[3] <= 0 || task->data[4] >= DISPLAY_WIDTH)
+ {
+ task->data[3] = 0;
+ task->data[4] = DISPLAY_WIDTH;
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ SetGpuReg(REG_OFFSET_BLDCNT, task->data[7]);
+ BlendPalettes(0xFFFFFFFF, 0, RGB_BLACK);
+ gPlttBufferFaded[0] = 0;
+ }
+ SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(task->data[3], task->data[4]));
+ if (task->data[3])
+ return;
+ break;
+ case 3:
+ task->data[5] -= task->data[2];
+ task->data[6] += task->data[2];
+ if (task->data[5] <= 0 || task->data[6] >= DISPLAY_HEIGHT)
+ {
+ task->data[5] = 0;
+ task->data[6] = DISPLAY_HEIGHT;
+ ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON);
+ }
+ SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(task->data[5], task->data[6]));
+ if (task->data[5])
+ return;
+ break;
+ default:
+ SetGpuReg(REG_OFFSET_BLDCNT, task->data[7]);
+ DestroyTask(taskId);
+ return;
+ }
+ ++task->data[0];
+}
+
+static void sub_80A0C78(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ gPlttBufferFaded[0] = 0;
+ break;
+ case 1:
+ task->data[3] = 0;
+ task->data[4] = DISPLAY_WIDTH;
+ task->data[5] = 0;
+ task->data[6] = DISPLAY_HEIGHT;
+ SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON);
+ SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(task->data[3], task->data[4]));
+ SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(task->data[5], task->data[6]));
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR);
+ SetGpuReg(REG_OFFSET_WINOUT, 0);
+ break;
+ case 2:
+ task->data[5] += task->data[2];
+ task->data[6] -= task->data[2];
+ if (task->data[5] >= 80 || task->data[6] <= 81)
+ {
+ task->data[5] = 80;
+ task->data[6] = 81;
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0 | BLDCNT_TGT1_BG1 | BLDCNT_TGT1_BG2 | BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_LIGHTEN);
+ SetGpuReg(REG_OFFSET_BLDY, 16);
+ }
+ SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(task->data[5], task->data[6]));
+ if (task->data[5] != 80)
+ return;
+ break;
+ case 3:
+ task->data[3] += task->data[1];
+ task->data[4] -= task->data[1];
+ if (task->data[3] >= 120 || task->data[4] <= 120)
+ {
+ task->data[3] = 120;
+ task->data[4] = 120;
+ BlendPalettes(0xFFFFFFFF, 0x10, RGB_BLACK);
+ gPlttBufferFaded[0] = 0;
+ }
+ SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(task->data[3], task->data[4]));
+ if (task->data[3] != 120)
+ return;
+ break;
+ default:
+ ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ DestroyTask(taskId);
+ return;
+ }
+ ++task->data[0];
+}
diff --git a/src/post_battle_event_funcs.c b/src/post_battle_event_funcs.c
index 1e61b9b77..112889710 100644
--- a/src/post_battle_event_funcs.c
+++ b/src/post_battle_event_funcs.c
@@ -1,5 +1,5 @@
#include "global.h"
-#include "script_pokemon_util_80A0058.h"
+#include "script_pokemon_util.h"
#include "event_data.h"
#include "credits.h"
#include "overworld.h"
diff --git a/src/quest_log.c b/src/quest_log.c
index 970071a0f..4d94c78ad 100644
--- a/src/quest_log.c
+++ b/src/quest_log.c
@@ -3119,7 +3119,7 @@ static const u16 *sub_8113FBC(const u16 *a0)
StringCopy(gStringVar1, ItemId_GetName(r5[0]));
if (r5[0] == ITEM_ESCAPE_ROPE)
{
- GetMapNameGeneric(gStringVar2, r5[2]);
+ GetMapNameGeneric(gStringVar2, (u8)r5[2]);
StringExpandPlaceholders(gStringVar4, gUnknown_841AFA6);
}
else if (r5[1] != 0xFFFF)
@@ -4373,7 +4373,7 @@ static u16 *sub_81157DC(u16 *a0, const u16 *a1)
static const u16 *sub_8115800(const u16 *a0)
{
const u16 *r4 = sub_8113E88(42, a0);
- GetMapNameGeneric(gStringVar1, r4[0]);
+ GetMapNameGeneric(gStringVar1, (u8)r4[0]);
StringExpandPlaceholders(gStringVar4, gUnknown_841B064);
return r4 + 1;
}
diff --git a/src/region_map.c b/src/region_map.c
new file mode 100644
index 000000000..271ce548f
--- /dev/null
+++ b/src/region_map.c
@@ -0,0 +1,4399 @@
+#include "global.h"
+#include "palette.h"
+#include "gpu_regs.h"
+#include "scanline_effect.h"
+#include "task.h"
+#include "m4a.h"
+#include "malloc.h"
+#include "overworld.h"
+#include "event_data.h"
+#include "region_map.h"
+#include "window.h"
+#include "sound.h"
+#include "party_menu.h"
+#include "field_effect.h"
+#include "new_menu_helpers.h"
+#include "menu.h"
+#include "string_util.h"
+#include "strings.h"
+#include "map_preview_screen.h"
+#include "constants/flags.h"
+#include "constants/songs.h"
+#include "constants/region_map.h"
+#include "constants/spawn_points.h"
+#include "constants/maps.h"
+
+#define FREE_IF_NOT_NULL(ptr) ({ \
+ if (ptr) { \
+ FREE_AND_SET_NULL(ptr); \
+ } \
+})
+
+struct UnkStruct_20399D4
+{
+ u8 field_0000[19];
+ u8 field_0013[19];
+ u16 layouts[5][600];
+ // Inefficiency: these should be u8 or have half the elements each
+ u16 bgTilemapBuffers[3][BG_SCREEN_SIZE];
+ u8 mapType;
+ bool8 regionMapPermissions[4];
+ u8 field_479B;
+ u8 field_479C;
+ u8 ALIGNED(4) field_47A0;
+ u8 ALIGNED(4) field_47A4;
+ u8 ALIGNED(4) field_47A8;
+ u16 field_47AA;
+ u16 field_47AC;
+ u16 field_47AE;
+ u16 field_47B0;
+ u8 filler_47B2[6];
+ TaskFunc field_47B8;
+ MainCallback savedCallback;
+}; // size = 0x47C0
+
+struct SelectionCursorSubspriteData
+{
+ u8 tiles[0x400];
+ struct Sprite * sprite;
+ u16 tileTag;
+ u16 paletteTag;
+ s16 xCoord;
+};
+
+struct UnkStruct_20399D8
+{
+ u8 bgTiles[0x1000];
+ u16 tileMap[0x258];
+ struct SelectionCursorSubspriteData selectionCursorSubspriteData[2];
+ u8 field_1CC8;
+ u8 selectionCursorLoadState;
+ u8 field_1CCA;
+ u8 field_1CCB;
+ u8 field_1CCC;
+ u8 field_1CCD;
+ u16 field_1CCE;
+ TaskFunc field_1CD0;
+ u16 field_1CD4[4];
+ u16 field_1CDC;
+}; // size = 0x1CE0
+
+struct GpuWindowParams
+{
+ u16 v0;
+ u16 v2;
+ u16 v4;
+ u16 v6;
+};
+
+struct UnkStruct_83F1B3C
+{
+ u16 id;
+ const u8 *name;
+ const u8 *desc;
+};
+
+struct DungeonMapPreviewManagerStruct
+{
+ u16 tiles[0x1C20];
+ u16 tilemap[0x280];
+ const struct MapPreviewScreen * mapPreviewInfo;
+ TaskFunc savedTask;
+ u8 dungeonMapPreviewPrepState;
+ u8 dungeonMapPreviewDrawState;
+ u8 field_3D4A;
+ u8 field_3D4B;
+ u8 field_3D4C;
+ u16 field_3D4E[0x30];
+ u8 filler_3DAE[0x60];
+ u16 field_3E0E;
+ u16 field_3E10;
+ u16 field_3E12;
+ u16 field_3E14;
+ u16 field_3E16;
+ u16 field_3E18;
+ u16 field_3E1A;
+ u16 field_3E1C;
+ u16 field_3E1E;
+ u16 field_3E20;
+ u16 field_3E22;
+ u16 field_3E24;
+}; // size = 0x3E28
+
+struct UnkStruct_20399E0_000
+{
+ u16 field_000[0x200];
+ struct Sprite * field_400;
+ s16 field_404;
+ s16 field_406;
+ u16 field_408;
+ u16 field_40A;
+};
+
+struct UnkStruct_20399E0
+{
+ struct UnkStruct_20399E0_000 * field_000[6];
+ u16 field_018[0x400];
+ u16 field_818[0x258];
+ TaskFunc field_CC8;
+ u8 field_CCC;
+ u8 field_CCD;
+ u8 field_CCE;
+ u8 field_CCF;
+ u8 field_CD0;
+}; // size = 0xCD4
+
+struct UnkStruct_20399E4
+{
+ s16 field_000;
+ s16 field_002;
+ u16 field_004;
+ u16 field_006;
+ s16 field_008;
+ s16 field_00A;
+ u16 field_00C;
+ u8 field_00E;
+ u8 (*field_010)(void);
+ u16 field_014;
+ u16 field_016;
+ u16 field_018;
+ struct Sprite * field_01C;
+ u16 field_020;
+ u16 field_022;
+ u16 field_024[0x80];
+}; // size = 0x124
+
+struct UnkStruct_20399E8
+{
+ s16 field_00;
+ s16 field_02;
+ struct Sprite * field_04;
+ u16 field_08;
+ u16 field_0A;
+ u16 field_0C[0x40];
+}; // size = 0x8C
+
+struct UnkStruct_20399EC_140
+{
+ u8 filler_0[4];
+ u8 field_4;
+ struct Sprite * field_8;
+ u16 field_C;
+ u16 field_E;
+};
+
+struct UnkStruct_20399EC
+{
+ u8 field_000[0x40];
+ u8 field_040[0x100];
+ struct UnkStruct_20399EC_140 field_140[25];
+ struct UnkStruct_20399EC_140 field_2D0[25];
+ u8 field_460;
+ u8 filler_461[2];
+ u8 field_463;
+ u8 filler_464[4];
+ TaskFunc field_468;
+}; // size = 0x46C
+
+struct UnkStruct_20399F0
+{
+ u16 bldcnt;
+ u16 bldy;
+ u16 bldalpha;
+ u16 winin;
+ u16 winout;
+ u16 win0h;
+ u16 win1h;
+ u16 win0v;
+ u16 win1v;
+};
+
+struct UnkStruct_20399FC
+{
+ u8 field_0;
+ u8 field_1;
+ u8 field_2;
+};
+
+static EWRAM_DATA struct UnkStruct_20399D4 * gUnknown_20399D4 = NULL;
+static EWRAM_DATA struct UnkStruct_20399D8 * gUnknown_20399D8 = NULL;
+static EWRAM_DATA struct DungeonMapPreviewManagerStruct * sDungeonMapPreviewManager = NULL;
+static EWRAM_DATA struct UnkStruct_20399E0 * gUnknown_20399E0 = NULL;
+static EWRAM_DATA struct UnkStruct_20399E4 * gUnknown_20399E4 = NULL;
+static EWRAM_DATA struct UnkStruct_20399E8 * gUnknown_20399E8 = NULL;
+static EWRAM_DATA struct UnkStruct_20399EC * gUnknown_20399EC = NULL;
+static EWRAM_DATA struct UnkStruct_20399F0 * gUnknown_20399F0[3] = {};
+static EWRAM_DATA struct UnkStruct_20399FC * gUnknown_20399FC = NULL;
+
+static void sub_80BFFD0(void);
+static void CB2_OpenRegionMap(void);
+static bool8 HandleLoadRegionMapGfx(void);
+static void sub_80C03E8(void);
+static void sub_80C04E4(u8 taskId);
+static void sub_80C07F8(u8 taskId);
+static void sub_80C0820(u8 taskId);
+static void sub_80C08B4(void);
+static void NullVBlankHBlankCallbacks(void);
+static void sub_80C08F4(void);
+static void ResetGpu(void);
+static void SetBgTilemapBuffers(void);
+static void ResetOamForRegionMap(void);
+static void SetBg0andBg3Visibility(u8 a0);
+static void sub_80C0AB8(void);
+static void sub_80C0B18(void);
+static void sub_80C0B9C(void);
+static void sub_80C0BB0(void);
+static void sub_80C0CC8(u8 bg, u16 *map);
+static bool8 GetRegionMapPermission(u8 a0);
+static u8 GetWhichRegionMap(void);
+static void sub_80C0E70(u8 a0, u8 taskId, TaskFunc taskFunc);
+static void sub_80C1098(u8 taskId);
+static void sub_80C1280(u8 taskId);
+static bool8 sub_80C12EC(void);
+static void sub_80C1324(u8 bg, u16 *map);
+static void sub_80C1390(void);
+static bool8 sub_80C144C(void);
+static bool8 sub_80C1478(void);
+static bool8 LoadAndCreateSelectionCursorSpriteGfx(void);
+static void CreateSelectionCursorSubsprite(u8 whichSprite, u16 tileTag, u16 paletteTag);
+static void RealCreateSelectionCursorSubsprite(u8 whichSprite, u16 tileTag, u16 paletteTag);
+static void DestroySelectionCursorSprites(void);
+static void RegionMapCreateDungeonMapPreview(u8 a0, u8 taskId, TaskFunc taskFunc);
+static void Task_PrepDungeonMapPreviewAndFlavorText(u8 taskId);
+static void Task_DrawDungeonMapPreviewAndFlavorText(u8 taskId);
+static void DestroyMapPreviewAssets(u8 taskId);
+static void sub_80C1E94(void);
+static void CopyMapPreviewTilemapToBgTilemapBuffer(u8 bgId, const u16 * tilemap);
+static bool8 sub_80C1F80(bool8 a0);
+static void sub_80C2208(u8 taskId, TaskFunc taskFunc);
+static void sub_80C24BC(void);
+static void sub_80C267C(u8 taskId);
+static void sub_80C25BC(void);
+static void sub_80C2604(void);
+static bool8 sub_80C29A4(void);
+static void sub_80C2B48(void);
+static void sub_80C2C1C(u8 taskId);
+static void sub_80C2C7C(u8 taskId);
+static bool8 sub_80C2E1C(void);
+static void sub_80C3008(u16 a0, u16 a1);
+static void sub_80C309C(void);
+static void sub_80C3154(bool8 a0);
+static void sub_80C3178(void);
+static void sub_80C3188(void);
+static u8 sub_80C31C0(void);
+static u8 sub_80C3348(void);
+static u8 sub_80C3400(void);
+static void sub_80C3418(void);
+static u16 GetMapCursorX(void);
+static u16 GetMapCursorY(void);
+static u16 sub_80C3520(void);
+static u16 GetMapSecUnderCursor(void);
+static u8 sub_80C35DC(u8 a0);
+static u8 sub_80C3878(u8 a0);
+static u8 sub_80C3AC8(u8 a0);
+static void GetPlayerPositionOnRegionMap_HandleOverrides(void);
+static u8 GetSelectedMapSection(u8 a0, u8 a1, s16 a2, s16 a3);
+static void sub_80C41D8(u16 a0, u16 a1);
+static void sub_80C4244(void);
+static void sub_80C4324(bool8 a0);
+static void sub_80C4348(void);
+static u16 sub_80C4380(void);
+static u16 sub_80C438C(void);
+static void sub_80C4398(u8 a0, u8 taskId, TaskFunc taskFunc);
+static void sub_80C440C(u8 taskId);
+static void sub_80C44E4(u8 taskId);
+static void sub_80C4750(void);
+static void sub_80C47F0(void);
+static void sub_80C48BC(u8 a0, u8 a1, bool8 a2);
+static void sub_80C4960(u8 a0, u8 a1, bool8 a2);
+static void sub_80C4A04(void);
+static bool8 sub_80C4AAC(u8 a0);
+static bool8 sub_80C4B30(u8 a0);
+static void sub_80C4BE4(void);
+static void sub_80C4C2C(u8 a0, u16 a1, u16 a2);
+static void sub_80C4C48(u16 a0);
+static void sub_80C4C5C(u16 a0, u16 a1);
+static void sub_80C4C74(u16 a0, u16 a1);
+static void sub_80C4C88(u16 a0);
+static void sub_80C4C9C(u8 a0, u8 a1);
+static void SetGpuWindowDims(u8 a0, const struct GpuWindowParams *a1);
+static void sub_80C4D30(void);
+static void sub_80C4E18(const u8 *str);
+static void sub_80C4E74(const u8 *str);
+static void sub_80C4ED0(bool8 a0);
+static void sub_80C4F08(u8 taskId);
+static void sub_80C51E8(void);
+static void sub_80C5208(u8 taskId);
+static void sub_80C527C(u16 a0);
+
+#include "data/text/map_section_names.h"
+
+static const u16 gUnknown_83EF23C[] = INCBIN_U16("graphics/region_map/unk_83EF23C.gbapal");
+static const u16 gUnknown_83EF25C[] = INCBIN_U16("graphics/region_map/unk_83EF25C.gbapal");
+static const u16 gUnknown_83EF27C[] = INCBIN_U16("graphics/region_map/unk_83EF27C.gbapal");
+static const u16 gUnknown_83EF29C[] = INCBIN_U16("graphics/region_map/unk_83EF29C.gbapal");
+static const u16 gUnknown_83EF2BC[] = INCBIN_U16("graphics/region_map/unk_83EF2BC.gbapal");
+static const u16 gUnknown_83EF2DC[] = INCBIN_U16("graphics/region_map/unk_83EF2DC.gbapal");
+static const u16 unref_83EF37C[] = {
+ RGB(0, 0, 31),
+ RGB(0, 12, 31),
+ RGB_WHITE,
+ RGB_WHITE
+};
+static const u16 sSelectionCursorPals[] = INCBIN_U16("graphics/region_map/unk_83EF384.gbapal");
+static const u16 gUnknown_83EF3A4[] = INCBIN_U16("graphics/region_map/unk_83EF3A4.gbapal");
+static const u32 sSelectionCursorLeftTiles[] = INCBIN_U32("graphics/region_map/unk_83EF3C4.4bpp.lz");
+static const u32 sSelectionCursorRightTiles[] = INCBIN_U32("graphics/region_map/unk_83EF450.4bpp.lz");
+static const u32 gUnknown_83EF4E0[] = INCBIN_U32("graphics/region_map/unk_83EF4E0.4bpp.lz");
+static const u32 gUnknown_83EF524[] = INCBIN_U32("graphics/region_map/unk_83EF524.4bpp.lz");
+static const u32 gUnknown_83EF59C[] = INCBIN_U32("graphics/region_map/unk_83EF59C.4bpp.lz");
+static const u32 gUnknown_83EF61C[] = INCBIN_U32("graphics/region_map/unk_83EF61C.4bpp.lz");
+static const u32 gUnknown_83F0330[] = INCBIN_U32("graphics/region_map/unk_83F0330.4bpp.lz");
+static const u32 gUnknown_83F0580[] = INCBIN_U32("graphics/region_map/unk_83F0580.bin.lz");
+static const u32 sRegionMapLayout_Kanto[] = INCBIN_U32("graphics/region_map/unk_83F089C.bin.lz");
+static const u32 sRegionMapLayout_Sevii123[] = INCBIN_U32("graphics/region_map/unk_83F0AFC.bin.lz");
+static const u32 sRegionMapLayout_Sevii45[] = INCBIN_U32("graphics/region_map/unk_83F0C0C.bin.lz");
+static const u32 sRegionMapLayout_Sevii67[] = INCBIN_U32("graphics/region_map/unk_83F0CF0.bin.lz");
+static const u32 gUnknown_83F0E0C[] = INCBIN_U32("graphics/region_map/unk_83F0E0C.bin.lz");
+static const u32 gUnknown_83F0F1C[] = INCBIN_U32("graphics/region_map/unk_83F0F1C.bin.lz");
+static const u32 gUnknown_83F1084[] = INCBIN_U32("graphics/region_map/unk_83F1084.bin.lz");
+static const u32 gUnknown_83F1190[] = INCBIN_U32("graphics/region_map/unk_83F1190.bin.lz");
+static const u32 gUnknown_83F12CC[] = INCBIN_U32("graphics/region_map/unk_83F12CC.4bpp.lz");
+static const u32 gUnknown_83F13EC[] = INCBIN_U32("graphics/region_map/unk_83F13EC.4bpp.lz");
+static const u32 gUnknown_83F1550[] = INCBIN_U32("graphics/region_map/unk_83F1550.4bpp.lz");
+static const u32 gUnknown_83F1640[] = INCBIN_U32("graphics/region_map/unk_83F1640.4bpp.lz");
+static const u32 gUnknown_83F1738[] = INCBIN_U32("graphics/region_map/unk_83F1738.4bpp.lz");
+static const u32 gUnknown_83F1804[] = INCBIN_U32("graphics/region_map/unk_83F1804.4bpp.lz");
+static const u32 gUnknown_83F18D8[] = INCBIN_U32("graphics/region_map/unk_83F18D8.4bpp.lz");
+static const u32 gUnknown_83F1908[] = INCBIN_U32("graphics/region_map/unk_83F1908.4bpp.lz");
+static const u32 gUnknown_83F1978[] = INCBIN_U32("graphics/region_map/unk_83F1978.4bpp.lz");
+static const u32 gUnknown_83F19A0[] = INCBIN_U32("graphics/region_map/unk_83F19A0.bin.lz");
+
+static const struct BgTemplate gUnknown_83F1A50[] = {
+ {
+ .bg = 0,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 30,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 2,
+ .baseTile = 0x000
+ }, {
+ .bg = 1,
+ .charBaseIndex = 1,
+ .mapBaseIndex = 15,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 3,
+ .baseTile = 0x000
+ }, {
+ .bg = 2,
+ .charBaseIndex = 2,
+ .mapBaseIndex = 23,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 1,
+ .baseTile = 0x000
+ }, {
+ .bg = 3,
+ .charBaseIndex = 3,
+ .mapBaseIndex = 31,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0x000
+ }
+};
+
+static const struct WindowTemplate gUnknown_83F1A60[] = {
+ {
+ .bg = 3,
+ .tilemapLeft = 3,
+ .tilemapTop = 2,
+ .width = 15,
+ .height = 2,
+ .paletteNum = 12,
+ .baseBlock = 0x001
+ }, {
+ .bg = 3,
+ .tilemapLeft = 3,
+ .tilemapTop = 4,
+ .width = 15,
+ .height = 2,
+ .paletteNum = 12,
+ .baseBlock = 0x01f
+ }, {
+ .bg = 3,
+ .tilemapLeft = 3,
+ .tilemapTop = 6,
+ .width = 25,
+ .height = 11,
+ .paletteNum = 12,
+ .baseBlock = 0x03d
+ }, {
+ .bg = 3,
+ .tilemapLeft = 18,
+ .tilemapTop = 0,
+ .width = 5,
+ .height = 2,
+ .paletteNum = 12,
+ .baseBlock = 0x150
+ }, {
+ .bg = 3,
+ .tilemapLeft = 24,
+ .tilemapTop = 0,
+ .width = 5,
+ .height = 2,
+ .paletteNum = 12,
+ .baseBlock = 0x15a
+ }, DUMMY_WIN_TEMPLATE
+};
+
+ALIGNED(4) const u8 sTextColor_White[] = {0, 1, 2};
+ALIGNED(4) const u8 sTextColor_Green[] = {0, 7, 2};
+ALIGNED(4) const u8 gUnknown_83F1A98[] = {0, 10, 2};
+
+static const u8 *const gUnknown_83F1A9C[] = {
+ sTextColor_Green,
+ gUnknown_83F1A98
+};
+
+static const u8 sSeviiMapsecs[3][30] = {
+ {
+ MAPSEC_ONE_ISLAND,
+ MAPSEC_TWO_ISLAND,
+ MAPSEC_THREE_ISLAND,
+ MAPSEC_KINDLE_ROAD,
+ MAPSEC_TREASURE_BEACH,
+ MAPSEC_CAPE_BRINK,
+ MAPSEC_BOND_BRIDGE,
+ MAPSEC_THREE_ISLE_PORT,
+ MAPSEC_MT_EMBER,
+ MAPSEC_BERRY_FOREST,
+ MAPSEC_THREE_ISLE_PATH,
+ MAPSEC_EMBER_SPA,
+ MAPSEC_NONE
+ }, {
+ MAPSEC_FOUR_ISLAND,
+ MAPSEC_FIVE_ISLAND,
+ MAPSEC_SEVII_ISLE_6,
+ MAPSEC_SEVII_ISLE_7,
+ MAPSEC_SEVII_ISLE_8,
+ MAPSEC_SEVII_ISLE_9,
+ MAPSEC_RESORT_GORGEOUS,
+ MAPSEC_WATER_LABYRINTH,
+ MAPSEC_FIVE_ISLE_MEADOW,
+ MAPSEC_MEMORIAL_PILLAR,
+ MAPSEC_NAVEL_ROCK,
+ MAPSEC_ICEFALL_CAVE,
+ MAPSEC_ROCKET_WAREHOUSE,
+ MAPSEC_LOST_CAVE,
+ MAPSEC_NONE
+ }, {
+ MAPSEC_SEVEN_ISLAND,
+ MAPSEC_SIX_ISLAND,
+ MAPSEC_OUTCAST_ISLAND,
+ MAPSEC_GREEN_PATH,
+ MAPSEC_WATER_PATH,
+ MAPSEC_RUIN_VALLEY,
+ MAPSEC_TRAINER_TOWER,
+ MAPSEC_CANYON_ENTRANCE,
+ MAPSEC_SEVAULT_CANYON,
+ MAPSEC_TANOBY_RUINS,
+ MAPSEC_SEVII_ISLE_22,
+ MAPSEC_SEVII_ISLE_23,
+ MAPSEC_SEVII_ISLE_24,
+ MAPSEC_TRAINER_TOWER_2,
+ MAPSEC_DOTTED_HOLE,
+ MAPSEC_PATTERN_BUSH,
+ MAPSEC_ALTERING_CAVE,
+ MAPSEC_TANOBY_CHAMBERS,
+ MAPSEC_TANOBY_KEY,
+ MAPSEC_BIRTH_ISLAND,
+ MAPSEC_MONEAN_CHAMBER,
+ MAPSEC_LIPTOO_CHAMBER,
+ MAPSEC_WEEPTH_CHAMBER,
+ MAPSEC_DILFORD_CHAMBER,
+ MAPSEC_SCUFIB_CHAMBER,
+ MAPSEC_RIXY_CHAMBER,
+ MAPSEC_VIAPOIS_CHAMBER,
+ MAPSEC_NONE
+ }
+};
+
+ALIGNED(4) const bool8 sRegionMapPermissions[3][4] = {
+ {TRUE , TRUE , TRUE , FALSE},
+ {FALSE, FALSE, FALSE, FALSE},
+ {FALSE, FALSE, FALSE, TRUE }
+};
+
+static const struct GpuWindowParams sStdWindowDims[3] = {
+ {0x18, 0x10, 0x90, 0x20},
+ {0x18, 0x20, 0x90, 0x30},
+ {0x00, 0x00, 0x00, 0x00}
+};
+
+static const struct OamData sSelectionCursorOam = {
+ .shape = SPRITE_SHAPE(32x32),
+ .size = SPRITE_SIZE(32x32)
+};
+
+static const union AnimCmd gUnknown_83F1B2C[] = {
+ ANIMCMD_FRAME(0x00, 20),
+ ANIMCMD_FRAME(0x10, 20),
+ ANIMCMD_JUMP(0)
+};
+
+static const union AnimCmd *const sSelectionCursorAnims[] = {
+ gUnknown_83F1B2C
+};
+
+static const struct UnkStruct_83F1B3C sDungeonHighlights[] = {
+ {
+ .id = MAPSEC_VIRIDIAN_FOREST,
+ .name = gMapSecName_ViridianForest,
+ .desc = gText_RegionMap_AreaDesc_ViridianForest
+ }, {
+ .id = MAPSEC_MT_MOON,
+ .name = gMapSecName_MtMoon,
+ .desc = gText_RegionMap_AreaDesc_MtMoon
+ }, {
+ .id = MAPSEC_DIGLETTS_CAVE,
+ .name = gMapSecName_DiglettsCave,
+ .desc = gText_RegionMap_AreaDesc_DiglettsCave
+ }, {
+ .id = MAPSEC_KANTO_VICTORY_ROAD,
+ .name = gMapSecName_VictoryRoad,
+ .desc = gText_RegionMap_AreaDesc_VictoryRoad
+ }, {
+ .id = MAPSEC_POKEMON_MANSION,
+ .name = gMapSecName_PokemonMansion,
+ .desc = gText_RegionMap_AreaDesc_PokemonMansion
+ }, {
+ .id = MAPSEC_KANTO_SAFARI_ZONE,
+ .name = gMapSecName_SafariZone,
+ .desc = gText_RegionMap_AreaDesc_SafariZone
+ }, {
+ .id = MAPSEC_ROCK_TUNNEL,
+ .name = gMapSecName_RockTunnel,
+ .desc = gText_RegionMap_AreaDesc_RockTunnel
+ }, {
+ .id = MAPSEC_SEAFOAM_ISLANDS,
+ .name = gMapSecName_SeafoamIslands,
+ .desc = gText_RegionMap_AreaDesc_SeafoamIslands
+ }, {
+ .id = MAPSEC_POKEMON_TOWER,
+ .name = gMapSecName_PokemonTower,
+ .desc = gText_RegionMap_AreaDesc_PokemonTower
+ }, {
+ .id = MAPSEC_CERULEAN_CAVE,
+ .name = gMapSecName_CeruleanCave,
+ .desc = gText_RegionMap_AreaDesc_CeruleanCave
+ }, {
+ .id = MAPSEC_POWER_PLANT,
+ .name = gMapSecName_PowerPlant,
+ .desc = gText_RegionMap_AreaDesc_PowerPlant
+ }, {
+ .id = MAPSEC_MT_EMBER,
+ .name = gMapSecName_MtEmber,
+ .desc = gText_RegionMap_AreaDesc_MtEmber
+ }, {
+ .id = MAPSEC_BERRY_FOREST,
+ .name = gMapSecName_BerryForest,
+ .desc = gText_RegionMap_AreaDesc_BerryForest
+ }, {
+ .id = MAPSEC_ICEFALL_CAVE,
+ .name = gMapSecName_IcefallCave,
+ .desc = gText_RegionMap_AreaDesc_IcefallCave
+ }, {
+ .id = MAPSEC_LOST_CAVE,
+ .name = gMapSecName_LostCave,
+ .desc = gText_RegionMap_AreaDesc_LostCave
+ }, {
+ .id = MAPSEC_TANOBY_CHAMBERS,
+ .name = gMapSecName_TanobyChambers,
+ .desc = gText_RegionMap_AreaDesc_TanobyRuins
+ }, {
+ .id = MAPSEC_ALTERING_CAVE,
+ .name = gMapSecName_AlteringCave,
+ .desc = gText_RegionMap_AreaDesc_AlteringCave
+ }, {
+ .id = MAPSEC_PATTERN_BUSH,
+ .name = gMapSecName_PatternBush,
+ .desc = gText_RegionMap_AreaDesc_PatternBush
+ }, {
+ .id = MAPSEC_DOTTED_HOLE,
+ .name = gMapSecName_DottedHole,
+ .desc = gText_RegionMap_AreaDesc_DottedHole
+ }
+};
+
+static const struct OamData gUnknown_83F1C20 = {
+ .shape = SPRITE_SHAPE(32x64),
+ .size = SPRITE_SIZE(32x64)
+};
+
+static const union AnimCmd gAnimCmd_83F1C28[] = {
+ ANIMCMD_FRAME(0, 0),
+ ANIMCMD_JUMP(0)
+};
+
+static const union AnimCmd *const gUnknown_83F1C30[] = {
+ gAnimCmd_83F1C28
+};
+
+static const struct GpuWindowParams gUnknown_83F1C34 = {
+ 0x18, 0x10, 0xD8, 0xA0
+};
+
+static const struct OamData gUnknown_83F1C3C = {
+ .shape = SPRITE_SHAPE(16x16),
+ .size = SPRITE_SIZE(16x16),
+ .priority = 2
+};
+
+static const union AnimCmd gAnimCmd_83F1C44[] = {
+ ANIMCMD_FRAME(0, 20),
+ ANIMCMD_FRAME(4, 20),
+ ANIMCMD_JUMP(0)
+};
+
+static const union AnimCmd *const gUnknown_83F1C50[] = {
+ gAnimCmd_83F1C44
+};
+
+static const struct OamData gUnknown_83F1C54 = {
+ .shape = SPRITE_SHAPE(16x16),
+ .size = SPRITE_SIZE(16x16),
+ .priority = 2
+};
+
+static const union AnimCmd gAnimCmd_83F1C5C[] = {
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const gUnknown_83F1C64[] = {
+ gAnimCmd_83F1C5C
+};
+
+static const struct OamData gUnknown_83F1C68 = {
+ .shape = SPRITE_SHAPE(16x16),
+ .size = SPRITE_SIZE(16x16),
+ .priority = 2
+};
+
+static const struct OamData gUnknown_83F1C70 = {
+ .shape = SPRITE_SHAPE(8x8),
+ .size = SPRITE_SIZE(8x8),
+ .priority = 2
+};
+
+static const union AnimCmd gAnimCmd_83F1C78[] = {
+ ANIMCMD_FRAME(0, 30),
+ ANIMCMD_FRAME(4, 60),
+ ANIMCMD_JUMP(0)
+};
+
+static const union AnimCmd gAnimCmd_83F1C84[] = {
+ ANIMCMD_FRAME(1, 20),
+ ANIMCMD_JUMP(0)
+};
+
+static const union AnimCmd gAnimCmd_83F1C8C[] = {
+ ANIMCMD_FRAME(0, 20),
+ ANIMCMD_JUMP(0)
+};
+
+static const union AnimCmd *const gUnknown_83F1C94[] = {
+ gAnimCmd_83F1C78
+};
+
+static const union AnimCmd *const gUnknown_83F1C98[] = {
+ gAnimCmd_83F1C84,
+ gAnimCmd_83F1C8C
+};
+
+static const u16 sWinFlags[] = {
+ DISPCNT_WIN0_ON,
+ DISPCNT_WIN1_ON
+};
+
+static const u8 sWinRegs[][2] = {
+ {REG_OFFSET_WIN0V, REG_OFFSET_WIN0H},
+ {REG_OFFSET_WIN1V, REG_OFFSET_WIN1H}
+};
+
+static const u8 gUnknown_83F1CA8[] = {15, 1, 2};
+
+static const u8 *const sMapNames[] = {
+ [MAPSEC_PALLET_TOWN - MAPSECS_KANTO] = gMapSecName_PalletTown,
+ [MAPSEC_VIRIDIAN_CITY - MAPSECS_KANTO] = gMapSecName_ViridianCity,
+ [MAPSEC_PEWTER_CITY - MAPSECS_KANTO] = gMapSecName_PewterCity,
+ [MAPSEC_CERULEAN_CITY - MAPSECS_KANTO] = gMapSecName_CeruleanCity,
+ [MAPSEC_LAVENDER_TOWN - MAPSECS_KANTO] = gMapSecName_LavenderTown,
+ [MAPSEC_VERMILION_CITY - MAPSECS_KANTO] = gMapSecName_VermilionCity,
+ [MAPSEC_CELADON_CITY - MAPSECS_KANTO] = gMapSecName_CeladonCity,
+ [MAPSEC_FUCHSIA_CITY - MAPSECS_KANTO] = gMapSecName_FuchsiaCity,
+ [MAPSEC_CINNABAR_ISLAND - MAPSECS_KANTO] = gMapSecName_CinnabarIsland,
+ [MAPSEC_INDIGO_PLATEAU - MAPSECS_KANTO] = gMapSecName_IndigoPlateau,
+ [MAPSEC_SAFFRON_CITY - MAPSECS_KANTO] = gMapSecName_SaffronCity,
+ [MAPSEC_ROUTE_4_FLYDUP - MAPSECS_KANTO] = gMapSecName_Route4,
+ [MAPSEC_ROUTE_10_FLYDUP - MAPSECS_KANTO] = gMapSecName_Route10,
+ [MAPSEC_ROUTE_1 - MAPSECS_KANTO] = gMapSecName_Route1,
+ [MAPSEC_ROUTE_2 - MAPSECS_KANTO] = gMapSecName_Route2,
+ [MAPSEC_ROUTE_3 - MAPSECS_KANTO] = gMapSecName_Route3,
+ [MAPSEC_ROUTE_4 - MAPSECS_KANTO] = gMapSecName_Route4_2,
+ [MAPSEC_ROUTE_5 - MAPSECS_KANTO] = gMapSecName_Route5,
+ [MAPSEC_ROUTE_6 - MAPSECS_KANTO] = gMapSecName_Route6,
+ [MAPSEC_ROUTE_7 - MAPSECS_KANTO] = gMapSecName_Route7,
+ [MAPSEC_ROUTE_8 - MAPSECS_KANTO] = gMapSecName_Route8,
+ [MAPSEC_ROUTE_9 - MAPSECS_KANTO] = gMapSecName_Route9,
+ [MAPSEC_ROUTE_10 - MAPSECS_KANTO] = gMapSecName_Route10_2,
+ [MAPSEC_ROUTE_11 - MAPSECS_KANTO] = gMapSecName_Route11,
+ [MAPSEC_ROUTE_12 - MAPSECS_KANTO] = gMapSecName_Route12,
+ [MAPSEC_ROUTE_13 - MAPSECS_KANTO] = gMapSecName_Route13,
+ [MAPSEC_ROUTE_14 - MAPSECS_KANTO] = gMapSecName_Route14,
+ [MAPSEC_ROUTE_15 - MAPSECS_KANTO] = gMapSecName_Route15,
+ [MAPSEC_ROUTE_16 - MAPSECS_KANTO] = gMapSecName_Route16,
+ [MAPSEC_ROUTE_17 - MAPSECS_KANTO] = gMapSecName_Route17,
+ [MAPSEC_ROUTE_18 - MAPSECS_KANTO] = gMapSecName_Route18,
+ [MAPSEC_ROUTE_19 - MAPSECS_KANTO] = gMapSecName_Route19,
+ [MAPSEC_ROUTE_20 - MAPSECS_KANTO] = gMapSecName_Route20,
+ [MAPSEC_ROUTE_21 - MAPSECS_KANTO] = gMapSecName_Route21,
+ [MAPSEC_ROUTE_22 - MAPSECS_KANTO] = gMapSecName_Route22,
+ [MAPSEC_ROUTE_23 - MAPSECS_KANTO] = gMapSecName_Route23,
+ [MAPSEC_ROUTE_24 - MAPSECS_KANTO] = gMapSecName_Route24,
+ [MAPSEC_ROUTE_25 - MAPSECS_KANTO] = gMapSecName_Route25,
+ [MAPSEC_VIRIDIAN_FOREST - MAPSECS_KANTO] = gMapSecName_ViridianForest,
+ [MAPSEC_MT_MOON - MAPSECS_KANTO] = gMapSecName_MtMoon,
+ [MAPSEC_S_S_ANNE - MAPSECS_KANTO] = gMapSecName_SSAnne,
+ [MAPSEC_UNDERGROUND_PATH - MAPSECS_KANTO] = gMapSecName_UndergroundPath,
+ [MAPSEC_UNDERGROUND_PATH_2 - MAPSECS_KANTO] = gMapSecName_UndergroundPath_2,
+ [MAPSEC_DIGLETTS_CAVE - MAPSECS_KANTO] = gMapSecName_DiglettsCave,
+ [MAPSEC_KANTO_VICTORY_ROAD - MAPSECS_KANTO] = gMapSecName_VictoryRoad,
+ [MAPSEC_ROCKET_HIDEOUT - MAPSECS_KANTO] = gMapSecName_RocketHideout,
+ [MAPSEC_SILPH_CO - MAPSECS_KANTO] = gMapSecName_SilphCo,
+ [MAPSEC_POKEMON_MANSION - MAPSECS_KANTO] = gMapSecName_PokemonMansion,
+ [MAPSEC_KANTO_SAFARI_ZONE - MAPSECS_KANTO] = gMapSecName_SafariZone,
+ [MAPSEC_POKEMON_LEAGUE - MAPSECS_KANTO] = gMapSecName_PokemonLeague,
+ [MAPSEC_ROCK_TUNNEL - MAPSECS_KANTO] = gMapSecName_RockTunnel,
+ [MAPSEC_SEAFOAM_ISLANDS - MAPSECS_KANTO] = gMapSecName_SeafoamIslands,
+ [MAPSEC_POKEMON_TOWER - MAPSECS_KANTO] = gMapSecName_PokemonTower,
+ [MAPSEC_CERULEAN_CAVE - MAPSECS_KANTO] = gMapSecName_CeruleanCave,
+ [MAPSEC_POWER_PLANT - MAPSECS_KANTO] = gMapSecName_PowerPlant,
+ [MAPSEC_ONE_ISLAND - MAPSECS_KANTO] = gMapSecName_OneIsland,
+ [MAPSEC_TWO_ISLAND - MAPSECS_KANTO] = gMapSecName_TwoIsland,
+ [MAPSEC_THREE_ISLAND - MAPSECS_KANTO] = gMapSecName_ThreeIsland,
+ [MAPSEC_FOUR_ISLAND - MAPSECS_KANTO] = gMapSecName_FourIsland,
+ [MAPSEC_FIVE_ISLAND - MAPSECS_KANTO] = gMapSecName_FiveIsland,
+ [MAPSEC_SEVEN_ISLAND - MAPSECS_KANTO] = gMapSecName_SevenIsland,
+ [MAPSEC_SIX_ISLAND - MAPSECS_KANTO] = gMapSecName_SixIsland,
+ [MAPSEC_KINDLE_ROAD - MAPSECS_KANTO] = gMapSecName_KindleRoad,
+ [MAPSEC_TREASURE_BEACH - MAPSECS_KANTO] = gMapSecName_TreasureBeach,
+ [MAPSEC_CAPE_BRINK - MAPSECS_KANTO] = gMapSecName_CapeBrink,
+ [MAPSEC_BOND_BRIDGE - MAPSECS_KANTO] = gMapSecName_BondBridge,
+ [MAPSEC_THREE_ISLE_PORT - MAPSECS_KANTO] = gMapSecName_ThreeIslePort,
+ [MAPSEC_SEVII_ISLE_6 - MAPSECS_KANTO] = gMapSecName_SeviiIsle6,
+ [MAPSEC_SEVII_ISLE_7 - MAPSECS_KANTO] = gMapSecName_SeviiIsle7,
+ [MAPSEC_SEVII_ISLE_8 - MAPSECS_KANTO] = gMapSecName_SeviiIsle8,
+ [MAPSEC_SEVII_ISLE_9 - MAPSECS_KANTO] = gMapSecName_SeviiIsle9,
+ [MAPSEC_RESORT_GORGEOUS - MAPSECS_KANTO] = gMapSecName_ResortGorgeous,
+ [MAPSEC_WATER_LABYRINTH - MAPSECS_KANTO] = gMapSecName_WaterLabyrinth,
+ [MAPSEC_FIVE_ISLE_MEADOW - MAPSECS_KANTO] = gMapSecName_FiveIsleMeadow,
+ [MAPSEC_MEMORIAL_PILLAR - MAPSECS_KANTO] = gMapSecName_MemorialPillar,
+ [MAPSEC_OUTCAST_ISLAND - MAPSECS_KANTO] = gMapSecName_OutcastIsland,
+ [MAPSEC_GREEN_PATH - MAPSECS_KANTO] = gMapSecName_GreenPath,
+ [MAPSEC_WATER_PATH - MAPSECS_KANTO] = gMapSecName_WaterPath,
+ [MAPSEC_RUIN_VALLEY - MAPSECS_KANTO] = gMapSecName_RuinValley,
+ [MAPSEC_TRAINER_TOWER - MAPSECS_KANTO] = gMapSecName_TrainerTower,
+ [MAPSEC_CANYON_ENTRANCE - MAPSECS_KANTO] = gMapSecName_CanyonEntrance,
+ [MAPSEC_SEVAULT_CANYON - MAPSECS_KANTO] = gMapSecName_SevaultCanyon,
+ [MAPSEC_TANOBY_RUINS - MAPSECS_KANTO] = gMapSecName_TanobyRuins,
+ [MAPSEC_SEVII_ISLE_22 - MAPSECS_KANTO] = gMapSecName_SeviiIsle22,
+ [MAPSEC_SEVII_ISLE_23 - MAPSECS_KANTO] = gMapSecName_SeviiIsle23,
+ [MAPSEC_SEVII_ISLE_24 - MAPSECS_KANTO] = gMapSecName_SeviiIsle24,
+ [MAPSEC_NAVEL_ROCK - MAPSECS_KANTO] = gMapSecName_NavelRock,
+ [MAPSEC_MT_EMBER - MAPSECS_KANTO] = gMapSecName_MtEmber,
+ [MAPSEC_BERRY_FOREST - MAPSECS_KANTO] = gMapSecName_BerryForest,
+ [MAPSEC_ICEFALL_CAVE - MAPSECS_KANTO] = gMapSecName_IcefallCave,
+ [MAPSEC_ROCKET_WAREHOUSE - MAPSECS_KANTO] = gMapSecName_RocketWarehouse,
+ [MAPSEC_TRAINER_TOWER_2 - MAPSECS_KANTO] = gMapSecName_TrainerTower_2,
+ [MAPSEC_DOTTED_HOLE - MAPSECS_KANTO] = gMapSecName_DottedHole,
+ [MAPSEC_LOST_CAVE - MAPSECS_KANTO] = gMapSecName_LostCave,
+ [MAPSEC_PATTERN_BUSH - MAPSECS_KANTO] = gMapSecName_PatternBush,
+ [MAPSEC_ALTERING_CAVE - MAPSECS_KANTO] = gMapSecName_AlteringCave,
+ [MAPSEC_TANOBY_CHAMBERS - MAPSECS_KANTO] = gMapSecName_TanobyChambers,
+ [MAPSEC_THREE_ISLE_PATH - MAPSECS_KANTO] = gMapSecName_ThreeIslePath,
+ [MAPSEC_TANOBY_KEY - MAPSECS_KANTO] = gMapSecName_TanobyKey,
+ [MAPSEC_BIRTH_ISLAND - MAPSECS_KANTO] = gMapSecName_BirthIsland,
+ [MAPSEC_MONEAN_CHAMBER - MAPSECS_KANTO] = gMapSecName_MoneanChamber,
+ [MAPSEC_LIPTOO_CHAMBER - MAPSECS_KANTO] = gMapSecName_LiptooChamber,
+ [MAPSEC_WEEPTH_CHAMBER - MAPSECS_KANTO] = gMapSecName_WeepthChamber,
+ [MAPSEC_DILFORD_CHAMBER - MAPSECS_KANTO] = gMapSecName_DilfordChamber,
+ [MAPSEC_SCUFIB_CHAMBER - MAPSECS_KANTO] = gMapSecName_ScufibChamber,
+ [MAPSEC_RIXY_CHAMBER - MAPSECS_KANTO] = gMapSecName_RixyChamber,
+ [MAPSEC_VIAPOIS_CHAMBER - MAPSECS_KANTO] = gMapSecName_ViapoisChamber,
+ [MAPSEC_EMBER_SPA - MAPSECS_KANTO] = gMapSecName_EmberSpa,
+ [MAPSEC_SPECIAL_AREA - MAPSECS_KANTO] = gMapSecName_CeladonDept
+};
+
+static const u16 sMapSectionTopLeftCorners[0xC6][2] = {
+ [MAPSEC_PALLET_TOWN - MAPSECS_KANTO] = {0x04, 0x0b},
+ [MAPSEC_VIRIDIAN_CITY - MAPSECS_KANTO] = {0x04, 0x08},
+ [MAPSEC_PEWTER_CITY - MAPSECS_KANTO] = {0x04, 0x04},
+ [MAPSEC_CERULEAN_CITY - MAPSECS_KANTO] = {0x0e, 0x03},
+ [MAPSEC_LAVENDER_TOWN - MAPSECS_KANTO] = {0x12, 0x06},
+ [MAPSEC_VERMILION_CITY - MAPSECS_KANTO] = {0x0e, 0x09},
+ [MAPSEC_CELADON_CITY - MAPSECS_KANTO] = {0x0b, 0x06},
+ [MAPSEC_FUCHSIA_CITY - MAPSECS_KANTO] = {0x0c, 0x0c},
+ [MAPSEC_CINNABAR_ISLAND - MAPSECS_KANTO] = {0x04, 0x0e},
+ [MAPSEC_INDIGO_PLATEAU - MAPSECS_KANTO] = {0x02, 0x03},
+ [MAPSEC_SAFFRON_CITY - MAPSECS_KANTO] = {0x0e, 0x06},
+ [MAPSEC_ROUTE_4_FLYDUP - MAPSECS_KANTO] = {0x08, 0x03},
+ [MAPSEC_ROUTE_10_FLYDUP - MAPSECS_KANTO] = {0x12, 0x03},
+ [MAPSEC_ROUTE_1 - MAPSECS_KANTO] = {0x04, 0x09},
+ [MAPSEC_ROUTE_2 - MAPSECS_KANTO] = {0x04, 0x05},
+ [MAPSEC_ROUTE_3 - MAPSECS_KANTO] = {0x05, 0x04},
+ [MAPSEC_ROUTE_4 - MAPSECS_KANTO] = {0x08, 0x03},
+ [MAPSEC_ROUTE_5 - MAPSECS_KANTO] = {0x0e, 0x04},
+ [MAPSEC_ROUTE_6 - MAPSECS_KANTO] = {0x0e, 0x07},
+ [MAPSEC_ROUTE_7 - MAPSECS_KANTO] = {0x0c, 0x06},
+ [MAPSEC_ROUTE_8 - MAPSECS_KANTO] = {0x0f, 0x06},
+ [MAPSEC_ROUTE_9 - MAPSECS_KANTO] = {0x0f, 0x03},
+ [MAPSEC_ROUTE_10 - MAPSECS_KANTO] = {0x12, 0x03},
+ [MAPSEC_ROUTE_11 - MAPSECS_KANTO] = {0x0f, 0x09},
+ [MAPSEC_ROUTE_12 - MAPSECS_KANTO] = {0x12, 0x07},
+ [MAPSEC_ROUTE_13 - MAPSECS_KANTO] = {0x10, 0x0b},
+ [MAPSEC_ROUTE_14 - MAPSECS_KANTO] = {0x0f, 0x0b},
+ [MAPSEC_ROUTE_15 - MAPSECS_KANTO] = {0x0d, 0x0c},
+ [MAPSEC_ROUTE_16 - MAPSECS_KANTO] = {0x07, 0x06},
+ [MAPSEC_ROUTE_17 - MAPSECS_KANTO] = {0x07, 0x07},
+ [MAPSEC_ROUTE_18 - MAPSECS_KANTO] = {0x07, 0x0c},
+ [MAPSEC_ROUTE_19 - MAPSECS_KANTO] = {0x0c, 0x0d},
+ [MAPSEC_ROUTE_20 - MAPSECS_KANTO] = {0x05, 0x0e},
+ [MAPSEC_ROUTE_21 - MAPSECS_KANTO] = {0x04, 0x0c},
+ [MAPSEC_ROUTE_22 - MAPSECS_KANTO] = {0x02, 0x08},
+ [MAPSEC_ROUTE_23 - MAPSECS_KANTO] = {0x02, 0x04},
+ [MAPSEC_ROUTE_24 - MAPSECS_KANTO] = {0x0e, 0x01},
+ [MAPSEC_ROUTE_25 - MAPSECS_KANTO] = {0x0f, 0x01},
+ [MAPSEC_ONE_ISLAND - MAPSECS_KANTO] = {0x01, 0x08},
+ [MAPSEC_TWO_ISLAND - MAPSECS_KANTO] = {0x09, 0x09},
+ [MAPSEC_THREE_ISLAND - MAPSECS_KANTO] = {0x12, 0x0c},
+ [MAPSEC_FOUR_ISLAND - MAPSECS_KANTO] = {0x03, 0x04},
+ [MAPSEC_FIVE_ISLAND - MAPSECS_KANTO] = {0x10, 0x0b},
+ [MAPSEC_SEVEN_ISLAND - MAPSECS_KANTO] = {0x05, 0x08},
+ [MAPSEC_SIX_ISLAND - MAPSECS_KANTO] = {0x11, 0x05},
+ [MAPSEC_KINDLE_ROAD - MAPSECS_KANTO] = {0x02, 0x03},
+ [MAPSEC_TREASURE_BEACH - MAPSECS_KANTO] = {0x01, 0x09},
+ [MAPSEC_CAPE_BRINK - MAPSECS_KANTO] = {0x09, 0x07},
+ [MAPSEC_BOND_BRIDGE - MAPSECS_KANTO] = {0x0d, 0x0c},
+ [MAPSEC_THREE_ISLE_PORT - MAPSECS_KANTO] = {0x12, 0x0d},
+ [MAPSEC_SEVII_ISLE_6 - MAPSECS_KANTO] = {0x04, 0x03},
+ [MAPSEC_SEVII_ISLE_7 - MAPSECS_KANTO] = {0x05, 0x04},
+ [MAPSEC_SEVII_ISLE_8 - MAPSECS_KANTO] = {0x01, 0x04},
+ [MAPSEC_SEVII_ISLE_9 - MAPSECS_KANTO] = {0x04, 0x05},
+ [MAPSEC_RESORT_GORGEOUS - MAPSECS_KANTO] = {0x10, 0x09},
+ [MAPSEC_WATER_LABYRINTH - MAPSECS_KANTO] = {0x0e, 0x0a},
+ [MAPSEC_FIVE_ISLE_MEADOW - MAPSECS_KANTO] = {0x11, 0x0a},
+ [MAPSEC_MEMORIAL_PILLAR - MAPSECS_KANTO] = {0x12, 0x0c},
+ [MAPSEC_OUTCAST_ISLAND - MAPSECS_KANTO] = {0x0f, 0x00},
+ [MAPSEC_GREEN_PATH - MAPSECS_KANTO] = {0x0f, 0x03},
+ [MAPSEC_WATER_PATH - MAPSECS_KANTO] = {0x12, 0x03},
+ [MAPSEC_RUIN_VALLEY - MAPSECS_KANTO] = {0x10, 0x07},
+ [MAPSEC_TRAINER_TOWER - MAPSECS_KANTO] = {0x05, 0x06},
+ [MAPSEC_CANYON_ENTRANCE - MAPSECS_KANTO] = {0x05, 0x09},
+ [MAPSEC_SEVAULT_CANYON - MAPSECS_KANTO] = {0x06, 0x09},
+ [MAPSEC_TANOBY_RUINS - MAPSECS_KANTO] = {0x03, 0x0c},
+ [MAPSEC_SEVII_ISLE_22 - MAPSECS_KANTO] = {0x09, 0x0c},
+ [MAPSEC_SEVII_ISLE_23 - MAPSECS_KANTO] = {0x03, 0x0e},
+ [MAPSEC_SEVII_ISLE_24 - MAPSECS_KANTO] = {0x02, 0x0c},
+ [MAPSEC_NAVEL_ROCK - MAPSECS_KANTO] = {0x0a, 0x08},
+ [MAPSEC_BIRTH_ISLAND - MAPSECS_KANTO] = {0x12, 0x0d},
+};
+
+static const u16 sMapSectionDimensions[0xC6][2] = {
+ [MAPSEC_PALLET_TOWN - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_VIRIDIAN_CITY - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_PEWTER_CITY - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_CERULEAN_CITY - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_LAVENDER_TOWN - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_VERMILION_CITY - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_CELADON_CITY - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_FUCHSIA_CITY - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_CINNABAR_ISLAND - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_INDIGO_PLATEAU - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_SAFFRON_CITY - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_ROUTE_4_FLYDUP - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_ROUTE_10_FLYDUP - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_ROUTE_1 - MAPSECS_KANTO] = {0x01, 0x02},
+ [MAPSEC_ROUTE_2 - MAPSECS_KANTO] = {0x01, 0x03},
+ [MAPSEC_ROUTE_3 - MAPSECS_KANTO] = {0x04, 0x01},
+ [MAPSEC_ROUTE_4 - MAPSECS_KANTO] = {0x06, 0x01},
+ [MAPSEC_ROUTE_5 - MAPSECS_KANTO] = {0x01, 0x02},
+ [MAPSEC_ROUTE_6 - MAPSECS_KANTO] = {0x01, 0x02},
+ [MAPSEC_ROUTE_7 - MAPSECS_KANTO] = {0x02, 0x01},
+ [MAPSEC_ROUTE_8 - MAPSECS_KANTO] = {0x03, 0x01},
+ [MAPSEC_ROUTE_9 - MAPSECS_KANTO] = {0x03, 0x01},
+ [MAPSEC_ROUTE_10 - MAPSECS_KANTO] = {0x01, 0x03},
+ [MAPSEC_ROUTE_11 - MAPSECS_KANTO] = {0x03, 0x01},
+ [MAPSEC_ROUTE_12 - MAPSECS_KANTO] = {0x01, 0x05},
+ [MAPSEC_ROUTE_13 - MAPSECS_KANTO] = {0x02, 0x01},
+ [MAPSEC_ROUTE_14 - MAPSECS_KANTO] = {0x01, 0x02},
+ [MAPSEC_ROUTE_15 - MAPSECS_KANTO] = {0x02, 0x01},
+ [MAPSEC_ROUTE_16 - MAPSECS_KANTO] = {0x04, 0x01},
+ [MAPSEC_ROUTE_17 - MAPSECS_KANTO] = {0x01, 0x05},
+ [MAPSEC_ROUTE_18 - MAPSECS_KANTO] = {0x05, 0x01},
+ [MAPSEC_ROUTE_19 - MAPSECS_KANTO] = {0x01, 0x02},
+ [MAPSEC_ROUTE_20 - MAPSECS_KANTO] = {0x07, 0x01},
+ [MAPSEC_ROUTE_21 - MAPSECS_KANTO] = {0x01, 0x02},
+ [MAPSEC_ROUTE_22 - MAPSECS_KANTO] = {0x02, 0x01},
+ [MAPSEC_ROUTE_23 - MAPSECS_KANTO] = {0x01, 0x04},
+ [MAPSEC_ROUTE_24 - MAPSECS_KANTO] = {0x01, 0x02},
+ [MAPSEC_ROUTE_25 - MAPSECS_KANTO] = {0x02, 0x01},
+ [MAPSEC_VIRIDIAN_FOREST - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_MT_MOON - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_S_S_ANNE - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_UNDERGROUND_PATH - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_UNDERGROUND_PATH_2 - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_DIGLETTS_CAVE - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_KANTO_VICTORY_ROAD - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_ROCKET_HIDEOUT - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_SILPH_CO - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_POKEMON_MANSION - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_KANTO_SAFARI_ZONE - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_POKEMON_LEAGUE - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_ROCK_TUNNEL - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_SEAFOAM_ISLANDS - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_POKEMON_TOWER - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_CERULEAN_CAVE - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_POWER_PLANT - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_ONE_ISLAND - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_TWO_ISLAND - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_THREE_ISLAND - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_FOUR_ISLAND - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_FIVE_ISLAND - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_SEVEN_ISLAND - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_SIX_ISLAND - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_KINDLE_ROAD - MAPSECS_KANTO] = {0x01, 0x06},
+ [MAPSEC_TREASURE_BEACH - MAPSECS_KANTO] = {0x01, 0x02},
+ [MAPSEC_CAPE_BRINK - MAPSECS_KANTO] = {0x01, 0x02},
+ [MAPSEC_BOND_BRIDGE - MAPSECS_KANTO] = {0x04, 0x01},
+ [MAPSEC_THREE_ISLE_PORT - MAPSECS_KANTO] = {0x02, 0x01},
+ [MAPSEC_SEVII_ISLE_6 - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_SEVII_ISLE_7 - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_SEVII_ISLE_8 - MAPSECS_KANTO] = {0x03, 0x01},
+ [MAPSEC_SEVII_ISLE_9 - MAPSECS_KANTO] = {0x01, 0x02},
+ [MAPSEC_RESORT_GORGEOUS - MAPSECS_KANTO] = {0x03, 0x01},
+ [MAPSEC_WATER_LABYRINTH - MAPSECS_KANTO] = {0x03, 0x01},
+ [MAPSEC_FIVE_ISLE_MEADOW - MAPSECS_KANTO] = {0x01, 0x03},
+ [MAPSEC_MEMORIAL_PILLAR - MAPSECS_KANTO] = {0x01, 0x03},
+ [MAPSEC_OUTCAST_ISLAND - MAPSECS_KANTO] = {0x01, 0x03},
+ [MAPSEC_GREEN_PATH - MAPSECS_KANTO] = {0x03, 0x01},
+ [MAPSEC_WATER_PATH - MAPSECS_KANTO] = {0x01, 0x05},
+ [MAPSEC_RUIN_VALLEY - MAPSECS_KANTO] = {0x02, 0x02},
+ [MAPSEC_TRAINER_TOWER - MAPSECS_KANTO] = {0x01, 0x02},
+ [MAPSEC_CANYON_ENTRANCE - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_SEVAULT_CANYON - MAPSECS_KANTO] = {0x01, 0x03},
+ [MAPSEC_TANOBY_RUINS - MAPSECS_KANTO] = {0x07, 0x01},
+ [MAPSEC_SEVII_ISLE_22 - MAPSECS_KANTO] = {0x01, 0x03},
+ [MAPSEC_SEVII_ISLE_23 - MAPSECS_KANTO] = {0x06, 0x01},
+ [MAPSEC_SEVII_ISLE_24 - MAPSECS_KANTO] = {0x01, 0x03},
+ [MAPSEC_NAVEL_ROCK - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_MT_EMBER - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_BERRY_FOREST - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_ICEFALL_CAVE - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_ROCKET_WAREHOUSE - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_TRAINER_TOWER_2 - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_DOTTED_HOLE - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_LOST_CAVE - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_PATTERN_BUSH - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_ALTERING_CAVE - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_TANOBY_CHAMBERS - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_THREE_ISLE_PATH - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_TANOBY_KEY - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_BIRTH_ISLAND - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_MONEAN_CHAMBER - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_LIPTOO_CHAMBER - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_WEEPTH_CHAMBER - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_DILFORD_CHAMBER - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_SCUFIB_CHAMBER - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_RIXY_CHAMBER - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_VIAPOIS_CHAMBER - MAPSECS_KANTO] = {0x01, 0x01},
+ [MAPSEC_EMBER_SPA - MAPSECS_KANTO] = {0x01, 0x01}
+};
+
+static const u8 sRegionMapSections_Kanto[][15][22] = {
+ {
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE,
+ MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE,
+ MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE,
+ MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_24, MAPSEC_ROUTE_25,
+ MAPSEC_ROUTE_25, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE,
+ MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_24, MAPSEC_NONE,
+ MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_INDIGO_PLATEAU, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE,
+ MAPSEC_NONE, MAPSEC_ROUTE_4_FLYDUP, MAPSEC_ROUTE_4, MAPSEC_ROUTE_4, MAPSEC_ROUTE_4, MAPSEC_ROUTE_4,
+ MAPSEC_ROUTE_4, MAPSEC_CERULEAN_CITY, MAPSEC_ROUTE_9, MAPSEC_ROUTE_9, MAPSEC_ROUTE_9, MAPSEC_ROUTE_10_FLYDUP,
+ MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_23, MAPSEC_NONE, MAPSEC_PEWTER_CITY, MAPSEC_ROUTE_3, MAPSEC_ROUTE_3,
+ MAPSEC_ROUTE_3, MAPSEC_ROUTE_3, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE,
+ MAPSEC_ROUTE_5, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_10, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_23, MAPSEC_NONE, MAPSEC_ROUTE_2, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE,
+ MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_5, MAPSEC_NONE,
+ MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_10, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_23, MAPSEC_NONE, MAPSEC_ROUTE_2, MAPSEC_NONE, MAPSEC_NONE,
+ MAPSEC_ROUTE_16, MAPSEC_ROUTE_16, MAPSEC_ROUTE_16, MAPSEC_ROUTE_16, MAPSEC_CELADON_CITY, MAPSEC_ROUTE_7,
+ MAPSEC_ROUTE_7, MAPSEC_SAFFRON_CITY, MAPSEC_ROUTE_8, MAPSEC_ROUTE_8, MAPSEC_ROUTE_8, MAPSEC_LAVENDER_TOWN,
+ MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_23, MAPSEC_NONE, MAPSEC_ROUTE_2, MAPSEC_NONE, MAPSEC_NONE,
+ MAPSEC_ROUTE_17, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_6,
+ MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_12, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_22, MAPSEC_ROUTE_22, MAPSEC_VIRIDIAN_CITY, MAPSEC_NONE, MAPSEC_NONE,
+ MAPSEC_ROUTE_17, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_6,
+ MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_12, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_1, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_17,
+ MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_VERMILION_CITY,
+ MAPSEC_ROUTE_11, MAPSEC_ROUTE_11, MAPSEC_ROUTE_11, MAPSEC_ROUTE_12, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_1, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_17,
+ MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE,
+ MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_12, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_PALLET_TOWN, MAPSEC_NONE, MAPSEC_NONE,
+ MAPSEC_ROUTE_17, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE,
+ MAPSEC_ROUTE_14, MAPSEC_ROUTE_13, MAPSEC_ROUTE_13, MAPSEC_ROUTE_12, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_21, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_18,
+ MAPSEC_ROUTE_18, MAPSEC_ROUTE_18, MAPSEC_ROUTE_18, MAPSEC_ROUTE_18, MAPSEC_FUCHSIA_CITY, MAPSEC_ROUTE_15,
+ MAPSEC_ROUTE_15, MAPSEC_ROUTE_14, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE,
+ MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_21, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE,
+ MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_19, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE,
+ MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_CINNABAR_ISLAND, MAPSEC_ROUTE_20, MAPSEC_ROUTE_20,
+ MAPSEC_ROUTE_20, MAPSEC_ROUTE_20, MAPSEC_ROUTE_20, MAPSEC_ROUTE_20, MAPSEC_ROUTE_20, MAPSEC_ROUTE_19,
+ MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE,
+ MAPSEC_NONE}
+ }, {
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_MT_MOON, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_CERULEAN_CAVE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROCK_TUNNEL, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_KANTO_VICTORY_ROAD, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_POWER_PLANT, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_DIGLETTS_CAVE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_VIRIDIAN_FOREST, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_POKEMON_TOWER, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_DIGLETTS_CAVE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_KANTO_SAFARI_ZONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_POKEMON_MANSION, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_SEAFOAM_ISLANDS, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE}
+ }
+};
+
+static const u8 sRegionMapSections_Sevii123[][15][22] = {
+ {
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_KINDLE_ROAD, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_KINDLE_ROAD, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_KINDLE_ROAD, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_KINDLE_ROAD, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_KINDLE_ROAD, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_CAPE_BRINK, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_ONE_ISLAND, MAPSEC_KINDLE_ROAD, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_CAPE_BRINK, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_TREASURE_BEACH, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_TWO_ISLAND, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_TREASURE_BEACH, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_BOND_BRIDGE, MAPSEC_BOND_BRIDGE, MAPSEC_BOND_BRIDGE, MAPSEC_BOND_BRIDGE, MAPSEC_THREE_ISLAND, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_THREE_ISLE_PORT, MAPSEC_THREE_ISLE_PORT, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE}
+ }, {
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_MT_EMBER, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_BERRY_FOREST, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE}
+ }
+};
+
+static const u8 sRegionMapSections_Sevii45[][15][22] = {
+ {
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_FOUR_ISLAND, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NAVEL_ROCK, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_RESORT_GORGEOUS, MAPSEC_RESORT_GORGEOUS, MAPSEC_RESORT_GORGEOUS, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_WATER_LABYRINTH, MAPSEC_WATER_LABYRINTH, MAPSEC_WATER_LABYRINTH, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_FIVE_ISLAND, MAPSEC_FIVE_ISLE_MEADOW, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_FIVE_ISLE_MEADOW, MAPSEC_MEMORIAL_PILLAR, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_MEMORIAL_PILLAR, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_MEMORIAL_PILLAR, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE}
+ }, {
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ICEFALL_CAVE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_LOST_CAVE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE}
+ }
+};
+
+static const u8 sRegionMapSections_Sevii67[][15][22] = {
+ {
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_OUTCAST_ISLAND, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_OUTCAST_ISLAND, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_OUTCAST_ISLAND, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_GREEN_PATH, MAPSEC_GREEN_PATH, MAPSEC_GREEN_PATH, MAPSEC_WATER_PATH, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_WATER_PATH, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_SIX_ISLAND, MAPSEC_WATER_PATH, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_TRAINER_TOWER, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_WATER_PATH, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_TRAINER_TOWER, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_RUIN_VALLEY, MAPSEC_RUIN_VALLEY, MAPSEC_WATER_PATH, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_SEVEN_ISLAND, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_RUIN_VALLEY, MAPSEC_RUIN_VALLEY, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_CANYON_ENTRANCE, MAPSEC_SEVAULT_CANYON, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_SEVAULT_CANYON, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_SEVAULT_CANYON, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_TANOBY_RUINS, MAPSEC_TANOBY_RUINS, MAPSEC_TANOBY_RUINS, MAPSEC_TANOBY_RUINS, MAPSEC_TANOBY_RUINS, MAPSEC_TANOBY_RUINS, MAPSEC_TANOBY_RUINS, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_BIRTH_ISLAND, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE}
+ }, {
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ALTERING_CAVE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_PATTERN_BUSH, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_DOTTED_HOLE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_TANOBY_CHAMBERS, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
+ {MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE}
+ }
+};
+
+static const u8 sMapsecToSpawn[][3] = {
+ [MAPSEC_PALLET_TOWN - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), SPAWN_PALLET_TOWN},
+ [MAPSEC_VIRIDIAN_CITY - MAPSECS_KANTO] = {MAP_GROUP(VIRIDIAN_CITY), MAP_NUM(VIRIDIAN_CITY), SPAWN_VIRIDIAN_CITY},
+ [MAPSEC_PEWTER_CITY - MAPSECS_KANTO] = {MAP_GROUP(PEWTER_CITY), MAP_NUM(PEWTER_CITY), SPAWN_PEWTER_CITY},
+ [MAPSEC_CERULEAN_CITY - MAPSECS_KANTO] = {MAP_GROUP(CERULEAN_CITY), MAP_NUM(CERULEAN_CITY), SPAWN_CERULEAN_CITY},
+ [MAPSEC_LAVENDER_TOWN - MAPSECS_KANTO] = {MAP_GROUP(LAVENDER_TOWN), MAP_NUM(LAVENDER_TOWN), SPAWN_LAVENDER_TOWN},
+ [MAPSEC_VERMILION_CITY - MAPSECS_KANTO] = {MAP_GROUP(VERMILION_CITY), MAP_NUM(VERMILION_CITY), SPAWN_VERMILION_CITY},
+ [MAPSEC_CELADON_CITY - MAPSECS_KANTO] = {MAP_GROUP(CELADON_CITY), MAP_NUM(CELADON_CITY), SPAWN_CELADON_CITY},
+ [MAPSEC_FUCHSIA_CITY - MAPSECS_KANTO] = {MAP_GROUP(FUCHSIA_CITY), MAP_NUM(FUCHSIA_CITY), SPAWN_FUCHSIA_CITY},
+ [MAPSEC_CINNABAR_ISLAND - MAPSECS_KANTO] = {MAP_GROUP(CINNABAR_ISLAND), MAP_NUM(CINNABAR_ISLAND), SPAWN_CINNABAR_ISLAND},
+ [MAPSEC_INDIGO_PLATEAU - MAPSECS_KANTO] = {MAP_GROUP(INDIGO_PLATEAU_EXTERIOR), MAP_NUM(INDIGO_PLATEAU_EXTERIOR), SPAWN_INDIGO_PLATEAU},
+ [MAPSEC_SAFFRON_CITY - MAPSECS_KANTO] = {MAP_GROUP(SAFFRON_CITY), MAP_NUM(SAFFRON_CITY), SPAWN_SAFFRON_CITY},
+ [MAPSEC_ROUTE_4_FLYDUP - MAPSECS_KANTO] = {MAP_GROUP(ROUTE4), MAP_NUM(ROUTE4), SPAWN_ROUTE4},
+ [MAPSEC_ROUTE_10_FLYDUP - MAPSECS_KANTO] = {MAP_GROUP(ROUTE10), MAP_NUM(ROUTE10), SPAWN_ROUTE10},
+ [MAPSEC_ROUTE_1 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE1), MAP_NUM(ROUTE1), 0},
+ [MAPSEC_ROUTE_2 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE2), MAP_NUM(ROUTE2), 0},
+ [MAPSEC_ROUTE_3 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE3), MAP_NUM(ROUTE3), 0},
+ [MAPSEC_ROUTE_4 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE4), MAP_NUM(ROUTE4), 0},
+ [MAPSEC_ROUTE_5 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE5), MAP_NUM(ROUTE5), 0},
+ [MAPSEC_ROUTE_6 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE6), MAP_NUM(ROUTE6), 0},
+ [MAPSEC_ROUTE_7 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE7), MAP_NUM(ROUTE7), 0},
+ [MAPSEC_ROUTE_8 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE8), MAP_NUM(ROUTE8), 0},
+ [MAPSEC_ROUTE_9 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE9), MAP_NUM(ROUTE9), 0},
+ [MAPSEC_ROUTE_10 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE10), MAP_NUM(ROUTE10), 0},
+ [MAPSEC_ROUTE_11 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE11), MAP_NUM(ROUTE11), 0},
+ [MAPSEC_ROUTE_12 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE12), MAP_NUM(ROUTE12), 0},
+ [MAPSEC_ROUTE_13 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE13), MAP_NUM(ROUTE13), 0},
+ [MAPSEC_ROUTE_14 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE14), MAP_NUM(ROUTE14), 0},
+ [MAPSEC_ROUTE_15 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE15), MAP_NUM(ROUTE15), 0},
+ [MAPSEC_ROUTE_16 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE16), MAP_NUM(ROUTE16), 0},
+ [MAPSEC_ROUTE_17 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE17), MAP_NUM(ROUTE17), 0},
+ [MAPSEC_ROUTE_18 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE18), MAP_NUM(ROUTE18), 0},
+ [MAPSEC_ROUTE_19 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE19), MAP_NUM(ROUTE19), 0},
+ [MAPSEC_ROUTE_20 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE20), MAP_NUM(ROUTE20), 0},
+ [MAPSEC_ROUTE_21 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE21_NORTH), MAP_NUM(ROUTE21_NORTH), 0},
+ [MAPSEC_ROUTE_22 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE22), MAP_NUM(ROUTE22), 0},
+ [MAPSEC_ROUTE_23 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE23), MAP_NUM(ROUTE23), 0},
+ [MAPSEC_ROUTE_24 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE24), MAP_NUM(ROUTE24), 0},
+ [MAPSEC_ROUTE_25 - MAPSECS_KANTO] = {MAP_GROUP(ROUTE25), MAP_NUM(ROUTE25), 0},
+ [MAPSEC_VIRIDIAN_FOREST - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_MT_MOON - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_S_S_ANNE - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_UNDERGROUND_PATH - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_UNDERGROUND_PATH_2 - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_DIGLETTS_CAVE - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_KANTO_VICTORY_ROAD - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_ROCKET_HIDEOUT - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_SILPH_CO - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_POKEMON_MANSION - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_KANTO_SAFARI_ZONE - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_POKEMON_LEAGUE - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_ROCK_TUNNEL - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_SEAFOAM_ISLANDS - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_POKEMON_TOWER - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_CERULEAN_CAVE - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_POWER_PLANT - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_ONE_ISLAND - MAPSECS_KANTO] = {MAP_GROUP(ONE_ISLAND), MAP_NUM(ONE_ISLAND), SPAWN_ONE_ISLAND},
+ [MAPSEC_TWO_ISLAND - MAPSECS_KANTO] = {MAP_GROUP(TWO_ISLAND), MAP_NUM(TWO_ISLAND), SPAWN_TWO_ISLAND},
+ [MAPSEC_THREE_ISLAND - MAPSECS_KANTO] = {MAP_GROUP(THREE_ISLAND), MAP_NUM(THREE_ISLAND), SPAWN_THREE_ISLAND},
+ [MAPSEC_FOUR_ISLAND - MAPSECS_KANTO] = {MAP_GROUP(FOUR_ISLAND), MAP_NUM(FOUR_ISLAND), SPAWN_FOUR_ISLAND},
+ [MAPSEC_FIVE_ISLAND - MAPSECS_KANTO] = {MAP_GROUP(FIVE_ISLAND), MAP_NUM(FIVE_ISLAND), SPAWN_FIVE_ISLAND},
+ [MAPSEC_SEVEN_ISLAND - MAPSECS_KANTO] = {MAP_GROUP(SEVEN_ISLAND), MAP_NUM(SEVEN_ISLAND), SPAWN_SEVEN_ISLAND},
+ [MAPSEC_SIX_ISLAND - MAPSECS_KANTO] = {MAP_GROUP(SIX_ISLAND), MAP_NUM(SIX_ISLAND), SPAWN_SIX_ISLAND},
+ [MAPSEC_KINDLE_ROAD - MAPSECS_KANTO] = {MAP_GROUP(ONE_ISLAND_KINDLE_ROAD), MAP_NUM(ONE_ISLAND_KINDLE_ROAD), 0},
+ [MAPSEC_TREASURE_BEACH - MAPSECS_KANTO] = {MAP_GROUP(ONE_ISLAND_TREASURE_BEACH), MAP_NUM(ONE_ISLAND_TREASURE_BEACH), 0},
+ [MAPSEC_CAPE_BRINK - MAPSECS_KANTO] = {MAP_GROUP(TWO_ISLAND_CAPE_BRINK), MAP_NUM(TWO_ISLAND_CAPE_BRINK), 0},
+ [MAPSEC_BOND_BRIDGE - MAPSECS_KANTO] = {MAP_GROUP(THREE_ISLAND_BOND_BRIDGE), MAP_NUM(THREE_ISLAND_BOND_BRIDGE), 0},
+ [MAPSEC_THREE_ISLE_PORT - MAPSECS_KANTO] = {MAP_GROUP(THREE_ISLAND_PORT), MAP_NUM(THREE_ISLAND_PORT), 0},
+ [MAPSEC_SEVII_ISLE_6 - MAPSECS_KANTO] = {MAP_GROUP(UNKNOWN_MAP_03_50), MAP_NUM(UNKNOWN_MAP_03_50), 0},
+ [MAPSEC_SEVII_ISLE_7 - MAPSECS_KANTO] = {MAP_GROUP(UNKNOWN_MAP_03_51), MAP_NUM(UNKNOWN_MAP_03_51), 0},
+ [MAPSEC_SEVII_ISLE_8 - MAPSECS_KANTO] = {MAP_GROUP(UNKNOWN_MAP_03_52), MAP_NUM(UNKNOWN_MAP_03_52), 0},
+ [MAPSEC_SEVII_ISLE_9 - MAPSECS_KANTO] = {MAP_GROUP(UNKNOWN_MAP_03_53), MAP_NUM(UNKNOWN_MAP_03_53), 0},
+ [MAPSEC_RESORT_GORGEOUS - MAPSECS_KANTO] = {MAP_GROUP(FIVE_ISLAND_RESORT_GORGEOUS), MAP_NUM(FIVE_ISLAND_RESORT_GORGEOUS), 0},
+ [MAPSEC_WATER_LABYRINTH - MAPSECS_KANTO] = {MAP_GROUP(FIVE_ISLAND_WATER_LABYRINTH), MAP_NUM(FIVE_ISLAND_WATER_LABYRINTH), 0},
+ [MAPSEC_FIVE_ISLE_MEADOW - MAPSECS_KANTO] = {MAP_GROUP(FIVE_ISLAND_MEADOW), MAP_NUM(FIVE_ISLAND_MEADOW), 0},
+ [MAPSEC_MEMORIAL_PILLAR - MAPSECS_KANTO] = {MAP_GROUP(FIVE_ISLAND_MEMORIAL_PILLAR), MAP_NUM(FIVE_ISLAND_MEMORIAL_PILLAR), 0},
+ [MAPSEC_OUTCAST_ISLAND - MAPSECS_KANTO] = {MAP_GROUP(SIX_ISLAND_OUTCAST_ISLAND), MAP_NUM(SIX_ISLAND_OUTCAST_ISLAND), 0},
+ [MAPSEC_GREEN_PATH - MAPSECS_KANTO] = {MAP_GROUP(SIX_ISLAND_GREEN_PATH), MAP_NUM(SIX_ISLAND_GREEN_PATH), 0},
+ [MAPSEC_WATER_PATH - MAPSECS_KANTO] = {MAP_GROUP(SIX_ISLAND_WATER_PATH), MAP_NUM(SIX_ISLAND_WATER_PATH), 0},
+ [MAPSEC_RUIN_VALLEY - MAPSECS_KANTO] = {MAP_GROUP(SIX_ISLAND_RUIN_VALLEY), MAP_NUM(SIX_ISLAND_RUIN_VALLEY), 0},
+ [MAPSEC_TRAINER_TOWER - MAPSECS_KANTO] = {MAP_GROUP(SEVEN_ISLAND_TRAINER_TOWER), MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER), 0},
+ [MAPSEC_CANYON_ENTRANCE - MAPSECS_KANTO] = {MAP_GROUP(SEVEN_ISLAND_SEVAULT_CANYON_ENTRANCE), MAP_NUM(SEVEN_ISLAND_SEVAULT_CANYON_ENTRANCE), 0},
+ [MAPSEC_SEVAULT_CANYON - MAPSECS_KANTO] = {MAP_GROUP(SEVEN_ISLAND_SEVAULT_CANYON), MAP_NUM(SEVEN_ISLAND_SEVAULT_CANYON), 0},
+ [MAPSEC_TANOBY_RUINS - MAPSECS_KANTO] = {MAP_GROUP(SEVEN_ISLAND_TANOBY_RUINS), MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS), 0},
+ [MAPSEC_SEVII_ISLE_22 - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_SEVII_ISLE_23 - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_SEVII_ISLE_24 - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_NAVEL_ROCK - MAPSECS_KANTO] = {MAP_GROUP(NAVEL_ROCK_EXTERIOR), MAP_NUM(NAVEL_ROCK_EXTERIOR), 0},
+ [MAPSEC_MT_EMBER - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_BERRY_FOREST - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_ICEFALL_CAVE - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_ROCKET_WAREHOUSE - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_TRAINER_TOWER_2 - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_DOTTED_HOLE - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_LOST_CAVE - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_PATTERN_BUSH - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_ALTERING_CAVE - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_TANOBY_CHAMBERS - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_THREE_ISLE_PATH - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_TANOBY_KEY - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_BIRTH_ISLAND - MAPSECS_KANTO] = {MAP_GROUP(BIRTH_ISLAND_EXTERIOR), MAP_NUM(BIRTH_ISLAND_EXTERIOR), 0},
+ [MAPSEC_MONEAN_CHAMBER - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_LIPTOO_CHAMBER - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_WEEPTH_CHAMBER - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_DILFORD_CHAMBER - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_SCUFIB_CHAMBER - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_RIXY_CHAMBER - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_VIAPOIS_CHAMBER - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+ [MAPSEC_EMBER_SPA - MAPSECS_KANTO] = {MAP_GROUP(PALLET_TOWN), MAP_NUM(PALLET_TOWN), 0},
+};
+
+static void RegionMap_DarkenPalette(u16 *pal, u16 size, u16 tint)
+{
+ int i;
+ int r, g, b;
+
+ for (i = 0; i < size; i++)
+ {
+ r = (*pal) & 0x1F;
+ g = ((*pal) >> 5) & 0x1F;
+ b = ((*pal) >> 10) & 0x1F;
+
+ r = (((r << 8) / 100) * tint) >> 8;
+ g = (((g << 8) / 100) * tint) >> 8;
+ b = (((b << 8) / 100) * tint) >> 8;
+
+ *pal = RGB2(r, g, b);
+ pal++;
+ }
+}
+
+static void sub_80BFEA0(void)
+{
+ u16 pal[16];
+ CpuCopy16(&gUnknown_83EF2DC[0x20], pal, sizeof(pal));
+ RegionMap_DarkenPalette(pal, NELEMS(pal), 95);
+ LoadPalette(pal, 0x20, 0x20);
+ LoadPalette(&gUnknown_83EF2DC[0x2F], 0x2F, sizeof(u16));
+}
+
+static void sub_80BFEDC(u8 kind)
+{
+ gUnknown_20399D4 = AllocZeroed(sizeof(struct UnkStruct_20399D4));
+ if (gUnknown_20399D4 == NULL)
+ {
+ SetMainCallback2(CB2_ReturnToField);
+ }
+ else
+ {
+ gUnknown_2031DE0 = TRUE;
+ gUnknown_20399D4->mapType = kind;
+ gUnknown_20399D4->field_47A0 = 0;
+ gUnknown_20399D4->field_47A4 = 0;
+ gUnknown_20399D4->field_47A8 = 0;
+ sub_80BFFD0();
+ SetMainCallback2(CB2_OpenRegionMap);
+ }
+}
+
+void sub_80BFF50(u8 kind, MainCallback cb)
+{
+ gUnknown_20399D4 = AllocZeroed(sizeof(struct UnkStruct_20399D4));
+ if (gUnknown_20399D4 == NULL)
+ {
+ SetMainCallback2(CB2_ReturnToField);
+ }
+ else
+ {
+ gUnknown_2031DE0 = TRUE;
+ gUnknown_20399D4->mapType = kind;
+ gUnknown_20399D4->field_47A0 = 0;
+ gUnknown_20399D4->field_47A4 = 0;
+ gUnknown_20399D4->field_47A8 = 0;
+ gUnknown_20399D4->savedCallback = cb;
+ sub_80BFFD0();
+ SetMainCallback2(CB2_OpenRegionMap);
+ }
+}
+
+static void sub_80BFFD0(void)
+{
+ u8 i;
+ u8 j;
+ u8 r7;
+
+ switch (gUnknown_20399D4->mapType)
+ {
+ default:
+ case 0:
+ case 1:
+ gUnknown_20399D4->field_47B8 = sub_80C04E4;
+ break;
+ case 2:
+ gUnknown_20399D4->field_47B8 = sub_80C4F08;
+ break;
+ }
+ for (i = 0; i < 4; i++)
+ {
+ gUnknown_20399D4->regionMapPermissions[i] = sRegionMapPermissions[gUnknown_20399D4->mapType][i];
+ }
+ if (!FlagGet(FLAG_SYS_SEVII_MAP_123))
+ gUnknown_20399D4->regionMapPermissions[MAPPERM_0] = FALSE;
+ r7 = 0;
+ j = 0;
+ if (gMapHeader.regionMapSectionId >= MAPSECS_SEVII_123)
+ {
+ while (r7 == 0)
+ {
+ for (i = 0; sSeviiMapsecs[j][i] != MAPSEC_NONE; i++)
+ {
+ if (gMapHeader.regionMapSectionId == sSeviiMapsecs[j][i])
+ {
+ r7 = j + 1;
+ break;
+ }
+ }
+ j++;
+ }
+ }
+ gUnknown_20399D4->field_479B = r7;
+ gUnknown_20399D4->field_479C = r7;
+}
+
+static void CB2_OpenRegionMap(void)
+{
+ switch (gUnknown_20399D4->field_47A4)
+ {
+ case 0:
+ NullVBlankHBlankCallbacks();
+ break;
+ case 1:
+ ResetGpu();
+ break;
+ case 2:
+ ResetOamForRegionMap();
+ break;
+ case 3:
+ if (!HandleLoadRegionMapGfx())
+ return;
+ break;
+ case 4:
+ FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 30, 20);
+ CopyBgTilemapBufferToVram(1);
+ break;
+ case 5:
+ sub_80C0CC8(0, gUnknown_20399D4->layouts[gUnknown_20399D4->field_479B]);
+ CopyBgTilemapBufferToVram(0);
+ if (gUnknown_20399D4->mapType != 0)
+ {
+ sub_80C0CC8(1, gUnknown_20399D4->layouts[4]);
+ CopyBgTilemapBufferToVram(1);
+ }
+ break;
+ case 6:
+ sub_80C0B18();
+ PutWindowTilemap(0);
+ break;
+ case 7:
+ sub_80C0BB0();
+ PutWindowTilemap(1);
+ break;
+ case 8:
+ if (GetRegionMapPermission(MAPPERM_2) == TRUE)
+ SetBg0andBg3Visibility(1);
+ break;
+ default:
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
+ sub_80C03E8();
+ sub_80C08F4();
+ break;
+ }
+ gUnknown_20399D4->field_47A4++;
+}
+
+static bool8 HandleLoadRegionMapGfx(void)
+{
+ switch (gUnknown_20399D4->field_47A8)
+ {
+ case 0:
+ LoadPalette(gUnknown_83EF23C, 0xC0, 0x20);
+ break;
+ case 1:
+ LoadPalette(gUnknown_83EF2DC, 0x00, 0xA0);
+ sub_80BFEA0();
+ if (gUnknown_20399D4->mapType != 0)
+ {
+ LoadPalette(&gUnknown_83EF23C[15], 0x00, 0x02);
+ LoadPalette(&gUnknown_83EF23C[15], 0x10, 0x02);
+ LoadPalette(&gUnknown_83EF23C[15], 0x20, 0x02);
+ LoadPalette(&gUnknown_83EF23C[15], 0x30, 0x02);
+ LoadPalette(&gUnknown_83EF23C[15], 0x40, 0x02);
+ }
+ break;
+ case 2:
+ ResetTempTileDataBuffers();
+ break;
+ case 3:
+ DecompressAndCopyTileDataToVram(0, gUnknown_83EF61C, 0, 0, 0);
+ if (gUnknown_20399D4->mapType != 0)
+ {
+ DecompressAndCopyTileDataToVram(1, gUnknown_83F1978, 0, 0, 0);
+ }
+ break;
+ case 4:
+ if (FreeTempTileDataBuffersIfPossible() == TRUE)
+ return FALSE;
+ break;
+ case 5:
+ LZ77UnCompWram(sRegionMapLayout_Kanto, gUnknown_20399D4->layouts[0]);
+ break;
+ case 6:
+ LZ77UnCompWram(sRegionMapLayout_Sevii123, gUnknown_20399D4->layouts[1]);
+ break;
+ case 7:
+ LZ77UnCompWram(sRegionMapLayout_Sevii45, gUnknown_20399D4->layouts[2]);
+ break;
+ case 8:
+ LZ77UnCompWram(sRegionMapLayout_Sevii67, gUnknown_20399D4->layouts[3]);
+ break;
+ default:
+ LZ77UnCompWram(gUnknown_83F19A0, gUnknown_20399D4->layouts[4]);
+ return TRUE;
+ }
+ gUnknown_20399D4->field_47A8++;
+ return FALSE;
+}
+
+static void sub_80C03E8(void)
+{
+ CreateTask(gUnknown_20399D4->field_47B8, 0);
+ SetMainCallback2(sub_80C08B4);
+}
+
+static bool32 sub_80C0410(void)
+{
+ if (GetSelectedMapSection(GetWhichRegionMap(), 0, GetMapCursorY(), GetMapCursorX()) == 99)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+static void sub_80C0450(void)
+{
+ if (sub_80C0410())
+ {
+ if ((sub_80C3AC8(0) != 1 && sub_80C3AC8(0) != 0) || (sub_80C3AC8(1) != 1 && sub_80C3AC8(1) != 0))
+ PlaySE(SE_Z_SCROLL);
+ if (GetMapCursorX() == 21 && GetMapCursorY() == 11 && GetRegionMapPermission(MAPPERM_0) == TRUE)
+ PlaySE(SE_W255);
+ else if (GetMapCursorX() == 21 && GetMapCursorY() == 13)
+ PlaySE(SE_W255);
+ }
+}
+
+static void sub_80C04E4(u8 taskId)
+{
+ switch (gUnknown_20399D4->field_47A0)
+ {
+ case 0:
+ sub_80C4398(GetWhichRegionMap(), taskId, gUnknown_20399D4->field_47B8);
+ sub_80C3008(0, 0);
+ sub_80C41D8(1, 1);
+ gUnknown_20399D4->field_47A0++;
+ break;
+ case 1:
+ if (gUnknown_20399D4->regionMapPermissions[MAPPERM_2] == TRUE)
+ {
+ sub_80C2208(taskId, gUnknown_20399D4->field_47B8);
+ }
+ else
+ {
+ ShowBg(0);
+ ShowBg(3);
+ ShowBg(1);
+ sub_80C4E18(gText_RegionMap_DPadMove);
+ sub_80C4E74(gText_RegionMap_Space);
+ sub_80C4ED0(FALSE);
+ sub_80C4324(FALSE);
+ sub_80C3154(FALSE);
+ sub_80C48BC(GetWhichRegionMap(), 25, FALSE);
+ sub_80C4960(GetWhichRegionMap(), 25, FALSE);
+ }
+ gUnknown_20399D4->field_47A0++;
+ break;
+ case 2:
+ if (!gPaletteFade.active && !IsDma3ManagerBusyWithBgCopy())
+ {
+ sub_80C0B18();
+ PutWindowTilemap(0);
+ sub_80C0BB0();
+ PutWindowTilemap(1);
+ gUnknown_20399D4->field_47A0++;
+ }
+ break;
+ case 3:
+ switch (sub_80C3400())
+ {
+ case 1:
+ sub_80C3178();
+ break;
+ case 2:
+ break;
+ case 3:
+ sub_80C0B18();
+ sub_80C0BB0();
+ sub_80C0B9C();
+ sub_80C0450();
+ if (GetMapSecUnderCursor() != MAPSEC_NONE)
+ {
+ if (GetRegionMapPermission(MAPPERM_1) == TRUE)
+ {
+ if (sub_80C3AC8(1) == 2)
+ {
+ sub_80C4E74(gText_RegionMap_AButtonGuide);
+ }
+ else
+ {
+ sub_80C4E74(gText_RegionMap_Space);
+ }
+ }
+ }
+ else
+ {
+ if (GetMapCursorX() == 21 && GetMapCursorY() == 11 && GetRegionMapPermission(MAPPERM_0) == TRUE)
+ {
+ sub_80C4E74(gText_RegionMap_AButtonSwitch);
+ }
+ else if (GetMapCursorX() == 21 && GetMapCursorY() == 13)
+ {
+ sub_80C4E74(gText_RegionMap_AButtonCancel);
+ }
+ else
+ {
+ sub_80C4E74(gText_RegionMap_Space);
+ }
+ }
+ break;
+ case 4:
+ if (sub_80C3AC8(1) == 2 && gUnknown_20399D4->regionMapPermissions[MAPPERM_1] == TRUE)
+ {
+ RegionMapCreateDungeonMapPreview(0, taskId, sub_80C07F8);
+ }
+ break;
+ case 5:
+ sub_80C0E70(gUnknown_20399D4->field_479B, taskId, sub_80C07F8);
+ break;
+ case 6:
+ gUnknown_20399D4->field_47A0++;
+ break;
+ }
+ break;
+ case 4:
+ if (GetRegionMapPermission(MAPPERM_2) == 1)
+ {
+ sub_80C2C1C(taskId);
+ // FIXME: goto required to match
+ // gUnknown_20399D4->field_47A0++;
+ goto _080C0798;
+ }
+ else
+ {
+ gUnknown_20399D4->field_47A0++;
+ }
+ break;
+ case 5:
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK);
+ _080C0798:
+ gUnknown_20399D4->field_47A0++;
+ break;
+ default:
+ if (!gPaletteFade.active)
+ {
+ sub_80C0820(taskId);
+ }
+ break;
+ }
+}
+
+static void sub_80C07D0(TaskFunc taskFunc)
+{
+ gUnknown_20399D4->field_47B8 = taskFunc;
+}
+
+TaskFunc sub_80C07E4(void)
+{
+ return gUnknown_20399D4->field_47B8;
+}
+
+static void sub_80C07F8(u8 taskId)
+{
+ gTasks[taskId].func = gUnknown_20399D4->field_47B8;
+}
+
+static void sub_80C0820(u8 taskId)
+{
+ if (GetRegionMapPermission(MAPPERM_2) == TRUE)
+ sub_80C25BC();
+ sub_80C4A04();
+ sub_80C3188();
+ sub_80C4348();
+ sub_80C4D30();
+ DestroyTask(taskId);
+ FreeAllWindowBuffers();
+ if (gUnknown_20399D4->savedCallback == NULL)
+ SetMainCallback2(gMain.savedCallback);
+ else
+ SetMainCallback2(gUnknown_20399D4->savedCallback);
+ FREE_IF_NOT_NULL(gUnknown_20399D4);
+}
+
+static void sub_80C0898(void)
+{
+ FREE_IF_NOT_NULL(gUnknown_20399D4);
+}
+
+static void sub_80C08B4(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+static void sub_80C08CC(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+static void NullVBlankHBlankCallbacks(void)
+{
+ SetVBlankCallback(NULL);
+ SetHBlankCallback(NULL);
+}
+
+static void sub_80C08F4(void)
+{
+ SetVBlankCallback(sub_80C08CC);
+}
+
+static void ResetGpu(void)
+{
+ DmaFillLarge16(3, 0, (void *)VRAM, VRAM_SIZE, 0x1000);
+ DmaFill32Defvars(3, 0, (void *)OAM, OAM_SIZE);
+ DmaFill16Defvars(3, 0, (void *)PLTT, PLTT_SIZE);
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ ResetBgsAndClearDma3BusyFlags(FALSE);
+ InitBgsFromTemplates(0, gUnknown_83F1A50, NELEMS(gUnknown_83F1A50));
+ ChangeBgX(0, 0, 0);
+ ChangeBgY(0, 0, 0);
+ ChangeBgX(1, 0, 0);
+ ChangeBgY(1, 0, 0);
+ ChangeBgX(2, 0, 0);
+ ChangeBgY(2, 0, 0);
+ ChangeBgX(3, 0, 0);
+ ChangeBgY(3, 0, 0);
+ InitWindows(gUnknown_83F1A60);
+ DeactivateAllTextPrinters();
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_WIN0_ON | DISPCNT_WIN1_ON);
+ SetBgTilemapBuffers();
+ sub_80C0AB8();
+}
+
+static void SetBgTilemapBuffers(void)
+{
+ SetBgTilemapBuffer(0, gUnknown_20399D4->bgTilemapBuffers[0]);
+ SetBgTilemapBuffer(1, gUnknown_20399D4->bgTilemapBuffers[1]);
+ SetBgTilemapBuffer(2, gUnknown_20399D4->bgTilemapBuffers[2]);
+}
+
+static void ResetOamForRegionMap(void)
+{
+ ResetSpriteData();
+ ResetPaletteFade();
+ FreeAllSpritePalettes();
+ ResetTasks();
+ ScanlineEffect_Stop();
+}
+
+static void SetBg0andBg3Visibility(u8 mode)
+{
+ switch (mode)
+ {
+ case 0:
+ ShowBg(0);
+ ShowBg(3);
+ break;
+ case 1:
+ HideBg(0);
+ HideBg(3);
+ break;
+ }
+}
+
+static void sub_80C0AB8(void)
+{
+ sub_80C4BE4();
+ sub_80C4C2C(0, 0x11, 0xc0);
+ sub_80C4C48(6);
+ sub_80C4C74(0x39, 0x39);
+ sub_80C4C88(0x1b);
+ SetGpuWindowDims(0, &sStdWindowDims[0]);
+ SetGpuWindowDims(1, &sStdWindowDims[1]);
+ sub_80C4C9C(0, 0);
+ if (GetMapSecUnderCursor() != MAPSEC_NONE)
+ sub_80C4C9C(1, 0);
+}
+
+static void sub_80C0B18(void)
+{
+ ClearWindowTilemap(0);
+ FillWindowPixelBuffer(0, PIXEL_FILL(0));
+ if (sub_80C3520() == MAPSEC_NONE)
+ {
+ SetGpuWindowDims(0, &sStdWindowDims[2]);
+ }
+ else
+ {
+ GetMapName(gUnknown_20399D4->field_0000, sub_80C3520(), 0);
+ AddTextPrinterParameterized3(0, 2, 2, 2, sTextColor_White, 0, gUnknown_20399D4->field_0000);
+ PutWindowTilemap(0);
+ CopyWindowToVram(0, 2);
+ SetGpuWindowDims(0, &sStdWindowDims[0]);
+ }
+}
+
+static void sub_80C0B9C(void)
+{
+ SetGpuWindowDims(1, &sStdWindowDims[1]);
+}
+
+static void sub_80C0BB0(void)
+{
+ u16 mapsecId;
+ u16 descOffset;
+ gUnknown_20399D4->field_47AC = 0;
+ gUnknown_20399D4->field_47AE = 24;
+ gUnknown_20399D4->field_47B0 = 32;
+ sub_80C4C9C(1, 1);
+ ClearWindowTilemap(1);
+ mapsecId = GetMapSecUnderCursor();
+ if (mapsecId != MAPSEC_NONE)
+ {
+ descOffset = mapsecId - MAPSECS_KANTO;
+ sub_80C4C9C(1, 0);
+ gUnknown_20399D4->field_47AC = 1;
+ gUnknown_20399D4->field_47AA = StringLength(sMapNames[descOffset]);
+ gUnknown_20399D4->field_47AE = gUnknown_20399D4->field_47AA * 10 + 50;
+ gUnknown_20399D4->field_47B0 = 48;
+ FillWindowPixelBuffer(1, PIXEL_FILL(0));
+ StringCopy(gUnknown_20399D4->field_0013, sMapNames[descOffset]);
+ AddTextPrinterParameterized3(1, 2, 12, 2, gUnknown_83F1A9C[sub_80C3AC8(1) - 2], 0, gUnknown_20399D4->field_0013);
+ PutWindowTilemap(1);
+ CopyWindowToVram(1, 3);
+ }
+}
+
+static void sub_80C0CA0(void)
+{
+ FillWindowPixelBuffer(0, PIXEL_FILL(0));
+ CopyWindowToVram(0, 3);
+ FillWindowPixelBuffer(1, PIXEL_FILL(0));
+ CopyWindowToVram(1, 3);
+}
+
+static void sub_80C0CC8(u8 bg, u16 *map)
+{
+ s16 i;
+ s16 j;
+ u8 r4;
+ u16 *buffer = gUnknown_20399D4->bgTilemapBuffers[bg];
+ for (i = 0; i < 20; i++)
+ {
+ for (j = 0; j < 32; j++)
+ {
+ if (j < 30)
+ buffer[32 * i + j] = map[30 * i + j];
+ else
+ buffer[32 * i + j] = map[0];
+ }
+ }
+ if (gUnknown_20399D4->regionMapPermissions[MAPPERM_0] == TRUE)
+ {
+ WriteSequenceToBgTilemapBuffer(0, 0x0F0, 0x18, 0x0E, 3, 1, 0x3, 0x001);
+ WriteSequenceToBgTilemapBuffer(0, 0x100, 0x18, 0x0F, 3, 1, 0x3, 0x001);
+ WriteSequenceToBgTilemapBuffer(0, 0x110, 0x18, 0x10, 3, 1, 0x3, 0x001);
+ }
+ if (gUnknown_20399D8 != NULL)
+ r4 = gUnknown_20399D8->field_1CCA;
+ else
+ r4 = gUnknown_20399D4->field_479B;
+ if (r4 == REGIONMAP_SEVII45 && !FlagGet(FLAG_WORLD_MAP_NAVEL_ROCK_EXTERIOR))
+ FillBgTilemapBufferRect_Palette0(0, 0x003, 13, 11, 3, 2);
+ if (r4 == REGIONMAP_SEVII67 && !FlagGet(FLAG_WORLD_MAP_BIRTH_ISLAND_EXTERIOR))
+ FillBgTilemapBufferRect_Palette0(0, 0x003, 21, 16, 3, 3);
+}
+
+static bool8 GetRegionMapPermission(u8 attr)
+{
+ return gUnknown_20399D4->regionMapPermissions[attr];
+}
+
+static u8 GetWhichRegionMap(void)
+{
+ return gUnknown_20399D4->field_479B;
+}
+
+static u8 sub_80C0E34(void)
+{
+ return gUnknown_20399D4->field_479C;
+}
+
+static void SetWhichRegionMap(u8 a0)
+{
+ gUnknown_20399D4->field_479B = a0;
+}
+
+static void sub_80C0E5C(u8 a0)
+{
+ gUnknown_20399D4->field_479C = a0;
+}
+
+static void sub_80C0E70(u8 a0, u8 taskId, TaskFunc taskFunc)
+{
+ gUnknown_20399D8 = AllocZeroed(sizeof(struct UnkStruct_20399D8));
+ if (FlagGet(FLAG_SYS_SEVII_MAP_4567))
+ gUnknown_20399D8->field_1CCC = 3;
+ else if (FlagGet(FLAG_SYS_SEVII_MAP_123))
+ gUnknown_20399D8->field_1CCC = 1;
+ else
+ gUnknown_20399D8->field_1CCC = 0;
+ gUnknown_20399D8->selectionCursorSubspriteData[0].xCoord = 0x58;
+ gUnknown_20399D8->selectionCursorSubspriteData[1].xCoord = 0x98;
+ switch (gUnknown_20399D8->field_1CCC)
+ {
+ case 1:
+ LZ77UnCompWram(gUnknown_83F1084, gUnknown_20399D8->tileMap);
+ gUnknown_20399D8->field_1CCE = 6;
+ break;
+ case 2: // never reached
+ LZ77UnCompWram(gUnknown_83F1190, gUnknown_20399D8->tileMap);
+ gUnknown_20399D8->field_1CCE = 4;
+ break;
+ case 3:
+ default:
+ gUnknown_20399D8->field_1CCE = 3;
+ LZ77UnCompWram(gUnknown_83F0F1C, gUnknown_20399D8->tileMap);
+ break;
+ }
+ LZ77UnCompWram(gUnknown_83F0580, gUnknown_20399D8->bgTiles);
+ gUnknown_20399D8->field_1CC8 = 0;
+ gUnknown_20399D8->field_1CCA = a0;
+ gUnknown_20399D8->field_1CD0 = taskFunc;
+ gUnknown_20399D8->field_1CCB = sub_80C0E34();
+ sub_80C4AAC(0);
+ sub_80C4E74(gText_RegionMap_AButtonOK);
+ gTasks[taskId].func = sub_80C1098;
+}
+
+static void sub_80C0FE0(void)
+{
+ sub_80C4BE4();
+ sub_80C4C2C(27, 4, 64);
+ sub_80C4C5C(16 - gUnknown_20399D8->field_1CCD, gUnknown_20399D8->field_1CCD);
+}
+
+static bool8 sub_80C1014(void)
+{
+ if (gUnknown_20399D8->field_1CCD < 16)
+ {
+ sub_80C4C5C(16 - gUnknown_20399D8->field_1CCD, gUnknown_20399D8->field_1CCD);
+ gUnknown_20399D8->field_1CCD += 2;
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+static bool8 sub_80C1058(void)
+{
+ if (gUnknown_20399D8->field_1CCD >= 2)
+ {
+ gUnknown_20399D8->field_1CCD -= 2;
+ sub_80C4C5C(16 - gUnknown_20399D8->field_1CCD, gUnknown_20399D8->field_1CCD);
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+static void sub_80C1098(u8 taskId)
+{
+ switch (gUnknown_20399D8->field_1CC8)
+ {
+ case 0:
+ NullVBlankHBlankCallbacks();
+ sub_80C4E18(gText_RegionMap_UpDownPick);
+ gUnknown_20399D8->field_1CC8++;
+ break;
+ case 1:
+ LoadBgTiles(2, gUnknown_20399D8->bgTiles, 0x1000, 0x000);
+ gUnknown_20399D8->field_1CC8++;
+ break;
+ case 2:
+ sub_80C1324(2, gUnknown_20399D8->tileMap);
+ CopyBgTilemapBufferToVram(2);
+ gUnknown_20399D8->field_1CC8++;
+ break;
+ case 3:
+ sub_80C0CA0();
+ gUnknown_20399D8->field_1CC8++;
+ break;
+ case 4:
+ sub_80C0FE0();
+ ShowBg(2);
+ gUnknown_20399D8->field_1CC8++;
+ break;
+ case 5:
+ sub_80C08F4();
+ gUnknown_20399D8->field_1CC8++;
+ break;
+ case 6:
+ if (sub_80C1014() == TRUE)
+ {
+ sub_80C1390();
+ gUnknown_20399D8->field_1CC8++;
+ }
+ break;
+ case 7:
+ if (sub_80C144C() == TRUE)
+ {
+ gUnknown_20399D8->field_1CC8++;
+ }
+ break;
+ case 8:
+ if (LoadAndCreateSelectionCursorSpriteGfx() == TRUE)
+ {
+ gUnknown_20399D8->field_1CC8++;
+ }
+ break;
+ case 9:
+ if (sub_80C1478() == TRUE)
+ {
+ SetWhichRegionMap(gUnknown_20399D8->field_1CCA);
+ if (sub_80C0E34() == gUnknown_20399D8->field_1CCA)
+ {
+ sub_80C4324(FALSE);
+ sub_80C48BC(gUnknown_20399D8->field_1CCA, 25, FALSE);
+ sub_80C4960(gUnknown_20399D8->field_1CCA, 25, FALSE);
+ }
+ gUnknown_20399D8->field_1CC8++;
+ }
+ break;
+ case 10:
+ if (sub_80C12EC() == TRUE)
+ {
+ DestroySelectionCursorSprites();
+ sub_80C0FE0();
+ gUnknown_20399D8->field_1CC8++;
+ }
+ break;
+ case 11:
+ if (sub_80C1058() == TRUE)
+ {
+ gUnknown_20399D8->field_1CC8++;
+ }
+ break;
+ case 12:
+ sub_80C3154(FALSE);
+ gUnknown_20399D8->field_1CC8++;
+ break;
+ default:
+ sub_80C1280(taskId);
+ break;
+ }
+}
+
+static void sub_80C1280(u8 taskId)
+{
+ gTasks[taskId].func = gUnknown_20399D8->field_1CD0;
+ HideBg(2);
+ sub_80C4E18(gText_RegionMap_DPadMove);
+ sub_80C4E74(gText_RegionMap_AButtonSwitch);
+ sub_80C0AB8();
+ sub_80C0B9C();
+ SetGpuWindowDims(0, &sStdWindowDims[2]);
+ FREE_IF_NOT_NULL(gUnknown_20399D8);
+}
+
+static bool8 sub_80C12EC(void)
+{
+ if (gUnknown_20399D8->field_1CDC != 0)
+ {
+ gUnknown_20399D8->field_1CDC--;
+ SetGpuReg(REG_OFFSET_BLDY, gUnknown_20399D8->field_1CDC);
+ return FALSE;
+ }
+ else
+ {
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ return TRUE;
+ }
+}
+
+static void sub_80C1324(u8 bg, u16 *map)
+{
+ s16 i;
+ s16 j;
+ u16 *buffer = gUnknown_20399D4->bgTilemapBuffers[bg];
+ for (i = 0; i < 20; i++)
+ {
+ for (j = 0; j < 32; j++)
+ {
+ if (j < 30)
+ buffer[32 * i + j] = map[30 * i + j];
+ else
+ buffer[32 * i + j] = map[0];
+ }
+ }
+}
+
+static void sub_80C1390(void)
+{
+ struct GpuWindowParams data;
+ data.v0 = gUnknown_20399D8->field_1CD4[0] = 0x48;
+ data.v2 = gUnknown_20399D8->field_1CD4[1] = 8 * (gUnknown_20399D8->field_1CCE + 4 * gUnknown_20399D8->field_1CCA);
+ data.v4 = gUnknown_20399D8->field_1CD4[2] = 0xA8;
+ data.v6 = gUnknown_20399D8->field_1CD4[3] = gUnknown_20399D8->field_1CD4[1] + 32;
+ sub_80C4BE4();
+ sub_80C4C2C(0, 0x15, 0xc0);
+ sub_80C4C74(0x1f, 0x15);
+ sub_80C4C88(0x3f);
+ sub_80C4C9C(1, 0);
+ SetGpuWindowDims(1, &data);
+}
+
+static bool8 sub_80C144C(void)
+{
+ if (gUnknown_20399D8->field_1CDC < 6)
+ {
+ gUnknown_20399D8->field_1CDC++;
+ sub_80C4C48(gUnknown_20399D8->field_1CDC);
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+static bool8 sub_80C1478(void)
+{
+ bool8 r6 = FALSE;
+ struct GpuWindowParams data;
+ data.v0 = gUnknown_20399D8->field_1CD4[0] = 0x48;
+ data.v2 = gUnknown_20399D8->field_1CD4[1] = 8 * (gUnknown_20399D8->field_1CCE + 4 * gUnknown_20399D8->field_1CCA);
+ data.v4 = gUnknown_20399D8->field_1CD4[2] = 0xA8;
+ data.v6 = gUnknown_20399D8->field_1CD4[3] = gUnknown_20399D8->field_1CD4[1] + 32;
+ if (JOY_NEW(DPAD_UP) && gUnknown_20399D8->field_1CCA != 0)
+ {
+ PlaySE(SE_BAG1);
+ gUnknown_20399D8->field_1CCA--;
+ r6 = TRUE;
+ }
+ if (JOY_NEW(DPAD_DOWN) && gUnknown_20399D8->field_1CCA < gUnknown_20399D8->field_1CCC)
+ {
+ PlaySE(SE_BAG1);
+ gUnknown_20399D8->field_1CCA++;
+ r6 = TRUE;
+ }
+ if (JOY_NEW(A_BUTTON) && gUnknown_20399D8->field_1CDC == 6)
+ {
+ PlaySE(SE_W129);
+ gUnknown_20399D8->field_1CCB = gUnknown_20399D8->field_1CCA;
+ return TRUE;
+ }
+ if (JOY_NEW(B_BUTTON))
+ {
+ gUnknown_20399D8->field_1CCA = gUnknown_20399D8->field_1CCB;
+ sub_80C0CC8(0, gUnknown_20399D4->layouts[gUnknown_20399D8->field_1CCA]);
+ CopyBgTilemapBufferToVram(0);
+ sub_80C48BC(255, 25, TRUE);
+ sub_80C4960(255, 25, TRUE);
+ return TRUE;
+ }
+ if (r6)
+ {
+ sub_80C0CC8(0, gUnknown_20399D4->layouts[gUnknown_20399D8->field_1CCA]);
+ sub_80C4E74(gText_RegionMap_AButtonOK);
+ CopyBgTilemapBufferToVram(0);
+ CopyBgTilemapBufferToVram(3);
+ sub_80C48BC(255, 25, TRUE);
+ sub_80C4960(255, 25, TRUE);
+ sub_80C48BC(gUnknown_20399D8->field_1CCA, 25, FALSE);
+ sub_80C4960(gUnknown_20399D8->field_1CCA, 25, FALSE);
+ }
+ if (gUnknown_20399D8->field_1CCA != sub_80C0E34())
+ sub_80C4324(TRUE);
+ else
+ sub_80C4324(FALSE);
+ SetGpuWindowDims(1, &data);
+ return FALSE;
+}
+
+static void SpriteCB_SelectionCursor(struct Sprite * sprite)
+{
+ sprite->pos1.y = gUnknown_20399D8->field_1CD4[1] + 16;
+}
+
+static bool8 LoadAndCreateSelectionCursorSpriteGfx(void)
+{
+ switch (gUnknown_20399D8->selectionCursorLoadState)
+ {
+ case 0:
+ LZ77UnCompWram(sSelectionCursorLeftTiles, gUnknown_20399D8->selectionCursorSubspriteData[0].tiles);
+ break;
+ case 1:
+ LZ77UnCompWram(sSelectionCursorRightTiles, gUnknown_20399D8->selectionCursorSubspriteData[1].tiles);
+ break;
+ case 2:
+ CreateSelectionCursorSubsprite(0, 2, 2);
+ CreateSelectionCursorSubsprite(1, 3, 3);
+ break;
+ default:
+ return TRUE;
+ }
+ gUnknown_20399D8->selectionCursorLoadState++;
+ return FALSE;
+}
+
+static void CreateSelectionCursorSubsprite(u8 whichSprite, u16 tileTag, u16 paletteTag)
+{
+ RealCreateSelectionCursorSubsprite(whichSprite, tileTag, paletteTag);
+}
+
+static void RealCreateSelectionCursorSubsprite(u8 whichSprite, u16 tileTag, u16 paletteTag)
+{
+ u8 spriteId;
+
+ struct SpriteSheet spriteSheet = {
+ .data = gUnknown_20399D8->selectionCursorSubspriteData[whichSprite].tiles,
+ .size = 0x400,
+ .tag = tileTag
+ };
+ struct SpritePalette spritePalette = {
+ .data = sSelectionCursorPals,
+ .tag = paletteTag
+ };
+ struct SpriteTemplate template = {
+ .tileTag = tileTag,
+ .paletteTag = paletteTag,
+ .oam = &sSelectionCursorOam,
+ .anims = sSelectionCursorAnims,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_SelectionCursor
+ };
+
+ gUnknown_20399D8->selectionCursorSubspriteData[whichSprite].tileTag = tileTag;
+ gUnknown_20399D8->selectionCursorSubspriteData[whichSprite].paletteTag = paletteTag;
+
+ LoadSpriteSheet(&spriteSheet);
+ LoadSpritePalette(&spritePalette);
+
+ spriteId = CreateSprite(&template, gUnknown_20399D8->selectionCursorSubspriteData[whichSprite].xCoord, 8 * (gUnknown_20399D8->field_1CCE + 4 * gUnknown_20399D8->field_1CCA), 0);
+ gUnknown_20399D8->selectionCursorSubspriteData[whichSprite].sprite = &gSprites[spriteId];
+ gSprites[spriteId].invisible = FALSE;
+}
+
+static void DestroySelectionCursorSprites(void)
+{
+ u8 i;
+ for (i = 0; i < 2; i++)
+ {
+ if (gUnknown_20399D8->selectionCursorSubspriteData[i].sprite != NULL)
+ {
+ DestroySprite(gUnknown_20399D8->selectionCursorSubspriteData[i].sprite);
+ FreeSpriteTilesByTag(gUnknown_20399D8->selectionCursorSubspriteData[i].tileTag);
+ FreeSpritePaletteByTag(gUnknown_20399D8->selectionCursorSubspriteData[i].paletteTag);
+ }
+ }
+}
+
+static const u8 *GetDungeonFlavorText(u16 mapsec)
+{
+ u8 i;
+ for (i = 0; i < NELEMS(sDungeonHighlights); i++)
+ {
+ if (sDungeonHighlights[i].id == mapsec)
+ return sDungeonHighlights[i].desc;
+ }
+ return gText_RegionMap_NoData;
+}
+
+static const u8 *GetDungeonName(u16 mapsec)
+{
+ u8 i;
+ for (i = 0; i < NELEMS(sDungeonHighlights); i++)
+ {
+ if (sDungeonHighlights[i].id == mapsec)
+ return sDungeonHighlights[i].name;
+ }
+ return gText_RegionMap_NoData;
+}
+
+static void RegionMapCreateDungeonMapPreview(u8 a0, u8 taskId, TaskFunc taskFunc)
+{
+ u8 r0;
+ sDungeonMapPreviewManager = AllocZeroed(sizeof(struct DungeonMapPreviewManagerStruct));
+ r0 = GetMapSecUnderCursor();
+ if (r0 == MAPSEC_TANOBY_CHAMBERS)
+ r0 = MAPSEC_MONEAN_CHAMBER;
+ sDungeonMapPreviewManager->mapPreviewInfo = GetDungeonMapPreviewScreenInfo(r0);
+ if (sDungeonMapPreviewManager->mapPreviewInfo == NULL)
+ sDungeonMapPreviewManager->mapPreviewInfo = GetDungeonMapPreviewScreenInfo(MAPSEC_ROCK_TUNNEL);
+ sDungeonMapPreviewManager->dungeonMapPreviewPrepState = 0;
+ sDungeonMapPreviewManager->field_3D4A = 0;
+ sDungeonMapPreviewManager->savedTask = taskFunc;
+ sDungeonMapPreviewManager->field_3E14 = 0;
+ sub_80C4AAC(0);
+ sub_80C4BE4();
+ sub_80C0CA0();
+ gTasks[taskId].func = Task_PrepDungeonMapPreviewAndFlavorText;
+}
+
+static bool8 HandleLoadMapPreviewScreenGfx(void)
+{
+ switch (sDungeonMapPreviewManager->field_3D4A)
+ {
+ case 0:
+ LZ77UnCompWram(sDungeonMapPreviewManager->mapPreviewInfo->tilesptr, sDungeonMapPreviewManager->tiles);
+ break;
+ case 1:
+ LZ77UnCompWram(sDungeonMapPreviewManager->mapPreviewInfo->tilemapptr, sDungeonMapPreviewManager->tilemap);
+ break;
+ case 2:
+ LoadBgTiles(2, sDungeonMapPreviewManager->tiles, 0x3840, 0x000);
+ break;
+ case 3:
+ LoadPalette(sDungeonMapPreviewManager->mapPreviewInfo->palptr, 0xD0, 0x60);
+ break;
+ default:
+ return TRUE;
+ }
+ sDungeonMapPreviewManager->field_3D4A++;
+ return FALSE;
+}
+
+static void Task_PrepDungeonMapPreviewAndFlavorText(u8 taskId)
+{
+ switch (sDungeonMapPreviewManager->dungeonMapPreviewPrepState)
+ {
+ case 0:
+ NullVBlankHBlankCallbacks();
+ sDungeonMapPreviewManager->dungeonMapPreviewPrepState++;
+ break;
+ case 1:
+ if (HandleLoadMapPreviewScreenGfx() == TRUE)
+ sDungeonMapPreviewManager->dungeonMapPreviewPrepState++;
+ break;
+ case 2:
+ sub_80C1E94();
+ sub_80C4E74(gText_RegionMap_AButtonCancel2);
+ sDungeonMapPreviewManager->dungeonMapPreviewPrepState++;
+ break;
+ case 3:
+ CopyMapPreviewTilemapToBgTilemapBuffer(2, sDungeonMapPreviewManager->tilemap);
+ CopyBgTilemapBufferToVram(2);
+ sDungeonMapPreviewManager->dungeonMapPreviewPrepState++;
+ break;
+ case 4:
+ ShowBg(2);
+ sDungeonMapPreviewManager->dungeonMapPreviewPrepState++;
+ break;
+ case 5:
+ sub_80C08F4();
+ sDungeonMapPreviewManager->dungeonMapPreviewPrepState++;
+ break;
+ case 6:
+ if (sub_80C1F80(FALSE) == TRUE)
+ sDungeonMapPreviewManager->dungeonMapPreviewPrepState++;
+ break;
+ case 7:
+ gTasks[taskId].func = Task_DrawDungeonMapPreviewAndFlavorText;
+ break;
+ case 8:
+ if (sub_80C1F80(TRUE) == TRUE)
+ {
+ sDungeonMapPreviewManager->dungeonMapPreviewPrepState++;
+ }
+ break;
+ case 9:
+ DestroyMapPreviewAssets(taskId);
+ sDungeonMapPreviewManager->dungeonMapPreviewPrepState++;
+ break;
+ }
+}
+
+static void Task_DrawDungeonMapPreviewAndFlavorText(u8 taskId)
+{
+ switch (sDungeonMapPreviewManager->dungeonMapPreviewDrawState)
+ {
+ case 0:
+ sDungeonMapPreviewManager->field_3E0E = 0x0133;
+ sDungeonMapPreviewManager->field_3E10 = 0x0100;
+ sDungeonMapPreviewManager->field_3E12 = 0x00F0;
+ sDungeonMapPreviewManager->dungeonMapPreviewDrawState++;
+ break;
+ case 1:
+ if (sDungeonMapPreviewManager->field_3D4C++ > 40)
+ {
+ sDungeonMapPreviewManager->field_3D4C = 0;
+ sDungeonMapPreviewManager->dungeonMapPreviewDrawState++;
+ }
+ break;
+ case 2:
+ FillWindowPixelBuffer(2, PIXEL_FILL(0));
+ CopyWindowToVram(2, 3);
+ PutWindowTilemap(2);
+ sDungeonMapPreviewManager->dungeonMapPreviewDrawState++;
+ break;
+ case 3:
+ if (sDungeonMapPreviewManager->field_3D4C > 25)
+ {
+ AddTextPrinterParameterized3(2, 2, 4, 0, sTextColor_Green, -1, GetDungeonName(GetMapSecUnderCursor()));
+ AddTextPrinterParameterized3(2, 2, 2, 14, sTextColor_White, -1, GetDungeonFlavorText(GetMapSecUnderCursor()));
+ CopyWindowToVram(2, 3);
+ sDungeonMapPreviewManager->dungeonMapPreviewDrawState++;
+ }
+ else if (sDungeonMapPreviewManager->field_3D4C > 20)
+ {
+ sDungeonMapPreviewManager->field_3E0E -= 6;
+ sDungeonMapPreviewManager->field_3E10 -= 5;
+ sDungeonMapPreviewManager->field_3E12 -= 5;
+ CpuCopy16(sDungeonMapPreviewManager->mapPreviewInfo->palptr, sDungeonMapPreviewManager->field_3D4E, 0x60);
+ TintPalette_CustomTone(sDungeonMapPreviewManager->field_3D4E, 0x30, sDungeonMapPreviewManager->field_3E0E, sDungeonMapPreviewManager->field_3E10, sDungeonMapPreviewManager->field_3E12);
+ LoadPalette(sDungeonMapPreviewManager->field_3D4E, 0xD0, 0x60);
+ }
+ sDungeonMapPreviewManager->field_3D4C++;
+ break;
+ case 4:
+ if (JOY_NEW(B_BUTTON) || JOY_NEW(A_BUTTON))
+ {
+ FillWindowPixelBuffer(2, PIXEL_FILL(0));
+ CopyWindowToVram(2, 3);
+ sDungeonMapPreviewManager->dungeonMapPreviewPrepState++;
+ sDungeonMapPreviewManager->dungeonMapPreviewDrawState++;
+ }
+ break;
+ default:
+ gTasks[taskId].func = Task_PrepDungeonMapPreviewAndFlavorText;
+ break;
+ }
+}
+
+static void DestroyMapPreviewAssets(u8 taskId)
+{
+ gTasks[taskId].func = sDungeonMapPreviewManager->savedTask;
+ HideBg(2);
+ sub_80C4B30(0);
+ sub_80C0B18();
+ sub_80C0BB0();
+ sub_80C0AB8();
+ sub_80C0B9C();
+ sub_80C4E74(gText_RegionMap_AButtonGuide);
+ FREE_IF_NOT_NULL(sDungeonMapPreviewManager);
+}
+
+static void CopyMapPreviewTilemapToBgTilemapBuffer(u8 bgId, const u16 * tilemap)
+{
+ CopyToBgTilemapBufferRect(2, tilemap, 0, 0, 32, 20);
+}
+
+static void sub_80C1E94(void)
+{
+ u16 r4;
+ u16 r0;
+ sub_80C4BE4();
+ sub_80C4C2C(0, 17, 192);
+ sub_80C4C48(sDungeonMapPreviewManager->field_3E14);
+ sub_80C4C74(0, 13);
+ sub_80C4C88(59);
+ sub_80C4C9C(1, 0);
+ r4 = GetMapCursorX();
+ r0 = GetMapCursorY();
+ sDungeonMapPreviewManager->field_3E16 = 8 * r4 + 32;
+ sDungeonMapPreviewManager->field_3E18 = 8 * r0 + 24;
+ sDungeonMapPreviewManager->field_3E1A = sDungeonMapPreviewManager->field_3E16 + 8;
+ sDungeonMapPreviewManager->field_3E1C = sDungeonMapPreviewManager->field_3E18 + 8;
+ sDungeonMapPreviewManager->field_3E1E = (0x10 - sDungeonMapPreviewManager->field_3E16) / 8;
+ sDungeonMapPreviewManager->field_3E20 = (0x20 - sDungeonMapPreviewManager->field_3E18) / 8;
+ sDungeonMapPreviewManager->field_3E22 = (0xE0 - sDungeonMapPreviewManager->field_3E1A) / 8;
+ sDungeonMapPreviewManager->field_3E24 = (0x88 - sDungeonMapPreviewManager->field_3E1C) / 8;
+}
+
+static bool8 sub_80C1F80(bool8 a0)
+{
+ struct GpuWindowParams data;
+
+ if (!a0)
+ {
+ if (sDungeonMapPreviewManager->field_3D4B < 8)
+ {
+ sDungeonMapPreviewManager->field_3E16 += sDungeonMapPreviewManager->field_3E1E;
+ sDungeonMapPreviewManager->field_3E18 += sDungeonMapPreviewManager->field_3E20;
+ sDungeonMapPreviewManager->field_3E1A += sDungeonMapPreviewManager->field_3E22;
+ sDungeonMapPreviewManager->field_3E1C += sDungeonMapPreviewManager->field_3E24;
+ sDungeonMapPreviewManager->field_3D4B++;
+ if (sDungeonMapPreviewManager->field_3E14 < 6)
+ sDungeonMapPreviewManager->field_3E14++;
+ }
+ else
+ {
+ return TRUE;
+ }
+ }
+ else
+ {
+ if (sDungeonMapPreviewManager->field_3D4B == 0)
+ {
+ return TRUE;
+ }
+ else
+ {
+ sDungeonMapPreviewManager->field_3E16 -= sDungeonMapPreviewManager->field_3E1E;
+ sDungeonMapPreviewManager->field_3E18 -= sDungeonMapPreviewManager->field_3E20;
+ sDungeonMapPreviewManager->field_3E1A -= sDungeonMapPreviewManager->field_3E22;
+ sDungeonMapPreviewManager->field_3E1C -= sDungeonMapPreviewManager->field_3E24;
+ sDungeonMapPreviewManager->field_3D4B--;
+ if (sDungeonMapPreviewManager->field_3E14 > 0)
+ sDungeonMapPreviewManager->field_3E14--;
+ }
+ }
+ data.v0 = sDungeonMapPreviewManager->field_3E16;
+ data.v2 = sDungeonMapPreviewManager->field_3E18;
+ data.v4 = sDungeonMapPreviewManager->field_3E1A;
+ data.v6 = sDungeonMapPreviewManager->field_3E1C;
+ SetGpuWindowDims(1, &data);
+ sub_80C4C48(sDungeonMapPreviewManager->field_3E14);
+ return FALSE;
+}
+
+static void nullsub_63(struct Sprite * sprite)
+{
+
+}
+
+static void sub_80C210C(u8 a0, u8 a1, u8 a2)
+{
+ u8 spriteId;
+ struct SpriteSheet spriteSheet = {
+ .data = gUnknown_20399E0->field_000[a0],
+ .size = 0x400,
+ .tag = a1
+ };
+ struct SpritePalette spritePalette = {
+ .data = gUnknown_83EF3A4,
+ .tag = a2
+ };
+ struct SpriteTemplate template = {
+ .tileTag = a1,
+ .paletteTag = a2,
+ .oam = &gUnknown_83F1C20,
+ .anims = gUnknown_83F1C30,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = nullsub_63
+ };
+
+ gUnknown_20399E0->field_000[a0]->field_408 = a1;
+ gUnknown_20399E0->field_000[a0]->field_40A = a2;
+ LoadSpriteSheet(&spriteSheet);
+ LoadSpritePalette(&spritePalette);
+ spriteId = CreateSprite(&template, gUnknown_20399E0->field_000[a0]->field_404, gUnknown_20399E0->field_000[a0]->field_406, 0);
+ gUnknown_20399E0->field_000[a0]->field_400 = &gSprites[spriteId];
+ gSprites[spriteId].invisible = TRUE;
+}
+
+static void sub_80C2208(u8 taskId, TaskFunc taskFunc)
+{
+ u8 i;
+
+ gUnknown_20399E0 = AllocZeroed(sizeof(struct UnkStruct_20399E0));
+ for (i = 0; i < 6; i++)
+ {
+ gUnknown_20399E0->field_000[i] = AllocZeroed(sizeof(struct UnkStruct_20399E0_000));
+ gUnknown_20399E0->field_000[i]->field_404 = 32 * (i / 3) + 0x68;
+ gUnknown_20399E0->field_000[i]->field_406 = 64 * (i % 3) + 0x28;
+ }
+ sub_80C4AAC(0);
+ sub_80C4BE4();
+ sub_80C24BC();
+ SetBg0andBg3Visibility(1);
+ gUnknown_20399E0->field_CC8 = taskFunc;
+ gTasks[taskId].func = sub_80C267C;
+}
+
+static void sub_80C22C4(u8 a0, bool8 a1)
+{
+ u8 i;
+ if (a0 == 6)
+ {
+ for (i = 0; i < 6; i++)
+ {
+ gUnknown_20399E0->field_000[i]->field_400->invisible = a1;
+ }
+ }
+ else
+ {
+ gUnknown_20399E0->field_000[a0]->field_400->invisible = a1;
+ }
+}
+
+static bool8 sub_80C2344(void)
+{
+ switch (gUnknown_20399E0->field_CCD)
+ {
+ case 0:
+ LZ77UnCompWram(gUnknown_83F12CC, gUnknown_20399E0->field_000[0]->field_000);
+ sub_80C210C(0, 4, 4);
+ break;
+ case 1:
+ LZ77UnCompWram(gUnknown_83F1550, gUnknown_20399E0->field_000[1]->field_000);
+ sub_80C210C(1, 5, 5);
+ break;
+ case 2:
+ LZ77UnCompWram(gUnknown_83F1738, gUnknown_20399E0->field_000[2]->field_000);
+ sub_80C210C(2, 6, 6);
+ break;
+ case 3:
+ LZ77UnCompWram(gUnknown_83F13EC, gUnknown_20399E0->field_000[3]->field_000);
+ sub_80C210C(3, 7, 7);
+ break;
+ case 4:
+ LZ77UnCompWram(gUnknown_83F1640, gUnknown_20399E0->field_000[4]->field_000);
+ sub_80C210C(4, 8, 8);
+ break;
+ case 5:
+ LZ77UnCompWram(gUnknown_83F1804, gUnknown_20399E0->field_000[5]->field_000);
+ sub_80C210C(5, 9, 9);
+ break;
+ case 6:
+ LZ77UnCompWram(gUnknown_83F0330, gUnknown_20399E0->field_018);
+ break;
+ case 7:
+ LZ77UnCompWram(gUnknown_83F0E0C, gUnknown_20399E0->field_818);
+ break;
+ case 8:
+ LoadBgTiles(1, gUnknown_20399E0->field_018, BG_SCREEN_SIZE, 0x000);
+ break;
+ default:
+ return TRUE;
+ }
+ gUnknown_20399E0->field_CCD++;
+ return FALSE;
+}
+
+static void sub_80C24BC(void)
+{
+ struct GpuWindowParams data;
+ data.v0 = gUnknown_20399E0->field_000[0]->field_404 + 8;
+ data.v2 = 0x10;
+ data.v4 = gUnknown_20399E0->field_000[3]->field_404 - 8;
+ data.v6 = 0xA0;
+ sub_80C4C2C(0, 2, 0);
+ sub_80C4C74(18, 0);
+ sub_80C4C88(16);
+ SetGpuWindowDims(0, &data);
+ sub_80C4C9C(0, 0);
+}
+
+static void sub_80C253C(void)
+{
+ struct GpuWindowParams data = gUnknown_83F1C34;
+ sub_80C4BE4();
+ sub_80C4C2C(2, 41, 128);
+ sub_80C4C48(gUnknown_20399E0->field_CD0);
+ sub_80C4C74(55, 0);
+ sub_80C4C88(18);
+ SetGpuWindowDims(0, &data);
+ sub_80C4C9C(0, 0);
+}
+
+static void sub_80C2594(u8 taskId)
+{
+ gTasks[taskId].func = gUnknown_20399E0->field_CC8;
+}
+
+static void sub_80C25BC(void)
+{
+ u8 i;
+ sub_80C2604();
+ for (i = 0; i < 6; i++)
+ {
+ FREE_IF_NOT_NULL(gUnknown_20399E0->field_000[i]);
+ }
+ FREE_IF_NOT_NULL(gUnknown_20399E0);
+}
+
+static void sub_80C2604(void)
+{
+ u8 i;
+ for (i = 0; i < 6; i++)
+ {
+ gUnknown_20399E0->field_000[i]->field_404 = gUnknown_20399E0->field_000[i]->field_400->pos1.x;
+ gUnknown_20399E0->field_000[i]->field_406 = gUnknown_20399E0->field_000[i]->field_400->pos1.y;
+ if (gUnknown_20399E0->field_000[i]->field_400 != NULL)
+ {
+ DestroySprite(gUnknown_20399E0->field_000[i]->field_400);
+ FreeSpriteTilesByTag(gUnknown_20399E0->field_000[i]->field_408);
+ FreeSpritePaletteByTag(gUnknown_20399E0->field_000[i]->field_40A);
+ }
+ }
+}
+
+static void sub_80C267C(u8 taskId)
+{
+ switch (gUnknown_20399E0->field_CCC)
+ {
+ case 0:
+ NullVBlankHBlankCallbacks();
+ gUnknown_20399E0->field_CCC++;
+ break;
+ case 1:
+ if (sub_80C2344() == TRUE)
+ gUnknown_20399E0->field_CCC++;
+ break;
+ case 2:
+ CopyToBgTilemapBufferRect(1, gUnknown_20399E0->field_818, 0, 0, 30, 20);
+ gUnknown_20399E0->field_CCC++;
+ break;
+ case 3:
+ CopyBgTilemapBufferToVram(1);
+ BlendPalettes(0xFFFFFFFF, 0x10, RGB_BLACK);
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
+ sub_80C08F4();
+ gUnknown_20399E0->field_CCC++;
+ break;
+ case 4:
+ ShowBg(0);
+ ShowBg(3);
+ ShowBg(1);
+ sub_80C22C4(6, FALSE);
+ sub_80C2B48();
+ gUnknown_20399E0->field_CCC++;
+ break;
+ case 5:
+ if (!gPaletteFade.active)
+ {
+ gUnknown_20399E0->field_CCC++;
+ PlaySE(SE_CARD3);
+ }
+ break;
+ case 6:
+ if (sub_80C29A4() == TRUE)
+ gUnknown_20399E0->field_CCC++;
+ break;
+ case 7:
+ sub_80C4324(FALSE);
+ sub_80C3154(FALSE);
+ gUnknown_20399E0->field_CCC++;
+ break;
+ case 8:
+ gUnknown_20399E0->field_CD0 = 15;
+ sub_80C253C();
+ SetBg0andBg3Visibility(0);
+ sub_80C48BC(GetWhichRegionMap(), 25, FALSE);
+ sub_80C4960(GetWhichRegionMap(), 25, FALSE);
+ gUnknown_20399E0->field_CCC++;
+ break;
+ case 9:
+ sub_80C4E18(gText_RegionMap_DPadMove);
+ if (sub_80C3AC8(1) != 2)
+ sub_80C4E74(gText_RegionMap_Space);
+ else
+ sub_80C4E74(gText_RegionMap_AButtonGuide);
+ sub_80C4ED0(FALSE);
+ gUnknown_20399E0->field_CCC++;
+ break;
+ case 10:
+ LoadPalette(&gUnknown_83EF23C[15], 0x00, 2);
+ LoadPalette(&gUnknown_83EF23C[15], 0x10, 2);
+ LoadPalette(&gUnknown_83EF23C[15], 0x20, 2);
+ LoadPalette(&gUnknown_83EF23C[15], 0x30, 2);
+ LoadPalette(&gUnknown_83EF23C[15], 0x40, 2);
+ gUnknown_20399E0->field_CCC++;
+ break;
+ case 11:
+ FillBgTilemapBufferRect(1, 0x002, 0, 1, 1, 1, 0x2);
+ FillBgTilemapBufferRect(1, 0x003, 1, 1, 1, 1, 0x2);
+ FillBgTilemapBufferRect(1, 0x03E, 28, 1, 1, 1, 0x2);
+ FillBgTilemapBufferRect(1, 0x03F, 29, 1, 1, 1, 0x2);
+ FillBgTilemapBufferRect(1, 0x03D, 2, 1, 26, 1, 0x2);
+ CopyBgTilemapBufferToVram(1);
+ m4aSongNumStop(SE_CARD3);
+ PlaySE(SE_HI_TURUN);
+ gUnknown_20399E0->field_CCC++;
+ break;
+ case 12:
+ if (gUnknown_20399E0->field_CD0 == 2)
+ {
+ sub_80C22C4(6, TRUE);
+ gUnknown_20399E0->field_CCC++;
+ sub_80C4C48(0);
+ }
+ else
+ {
+ gUnknown_20399E0->field_CD0--;
+ sub_80C4C48(gUnknown_20399E0->field_CD0);
+ }
+ break;
+ case 13:
+ sub_80C4B30(0);
+ sub_80C0BB0();
+ gUnknown_20399E0->field_CCC++;
+ break;
+ default:
+ sub_80C2604();
+ sub_80C2594(taskId);
+ break;
+ }
+}
+
+static bool8 sub_80C29A4(void)
+{
+ sub_80C2B48();
+ if (gUnknown_20399E0->field_000[0]->field_400->pos1.x == 0)
+ {
+ return TRUE;
+ }
+ else if (gUnknown_20399E0->field_CCE > 17)
+ {
+ gUnknown_20399E0->field_000[0]->field_400->pos1.x -= 1;
+ gUnknown_20399E0->field_000[1]->field_400->pos1.x -= 1;
+ gUnknown_20399E0->field_000[2]->field_400->pos1.x -= 1;
+ gUnknown_20399E0->field_000[3]->field_400->pos1.x += 1;
+ gUnknown_20399E0->field_000[4]->field_400->pos1.x += 1;
+ gUnknown_20399E0->field_000[5]->field_400->pos1.x += 1;
+ }
+ else if (gUnknown_20399E0->field_CCE > 14)
+ {
+ gUnknown_20399E0->field_000[0]->field_400->pos1.x -= 2;
+ gUnknown_20399E0->field_000[1]->field_400->pos1.x -= 2;
+ gUnknown_20399E0->field_000[2]->field_400->pos1.x -= 2;
+ gUnknown_20399E0->field_000[3]->field_400->pos1.x += 2;
+ gUnknown_20399E0->field_000[4]->field_400->pos1.x += 2;
+ gUnknown_20399E0->field_000[5]->field_400->pos1.x += 2;
+ }
+ else if (gUnknown_20399E0->field_CCE > 10)
+ {
+ gUnknown_20399E0->field_000[0]->field_400->pos1.x -= 3;
+ gUnknown_20399E0->field_000[1]->field_400->pos1.x -= 3;
+ gUnknown_20399E0->field_000[2]->field_400->pos1.x -= 3;
+ gUnknown_20399E0->field_000[3]->field_400->pos1.x += 3;
+ gUnknown_20399E0->field_000[4]->field_400->pos1.x += 3;
+ gUnknown_20399E0->field_000[5]->field_400->pos1.x += 3;
+ }
+ else if (gUnknown_20399E0->field_CCE > 6)
+ {
+ gUnknown_20399E0->field_000[0]->field_400->pos1.x -= 5;
+ gUnknown_20399E0->field_000[1]->field_400->pos1.x -= 5;
+ gUnknown_20399E0->field_000[2]->field_400->pos1.x -= 5;
+ gUnknown_20399E0->field_000[3]->field_400->pos1.x += 5;
+ gUnknown_20399E0->field_000[4]->field_400->pos1.x += 5;
+ gUnknown_20399E0->field_000[5]->field_400->pos1.x += 5;
+ }
+ else
+ {
+ gUnknown_20399E0->field_000[0]->field_400->pos1.x -= 8;
+ gUnknown_20399E0->field_000[1]->field_400->pos1.x -= 8;
+ gUnknown_20399E0->field_000[2]->field_400->pos1.x -= 8;
+ gUnknown_20399E0->field_000[3]->field_400->pos1.x += 8;
+ gUnknown_20399E0->field_000[4]->field_400->pos1.x += 8;
+ gUnknown_20399E0->field_000[5]->field_400->pos1.x += 8;
+ }
+ gUnknown_20399E0->field_CCE++;
+ return FALSE;
+}
+
+static void sub_80C2B48(void)
+{
+ struct GpuWindowParams data;
+ data.v0 = gUnknown_20399E0->field_000[0]->field_400->pos1.x;
+ data.v2 = 0x10;
+ data.v4 = gUnknown_20399E0->field_000[3]->field_400->pos1.x;
+ data.v6 = 0xA0;
+ SetGpuWindowDims(0, &data);
+}
+
+static void sub_80C2B9C(void)
+{
+ struct GpuWindowParams data;
+ data.v0 = gUnknown_20399E0->field_000[0]->field_404 + 16;
+ data.v2 = 0x10;
+ data.v4 = gUnknown_20399E0->field_000[3]->field_404 - 16;
+ data.v6 = 0xA0;
+ sub_80C4C2C(0, 2, 0);
+ sub_80C4C74(18, 0);
+ sub_80C4C88(16);
+ SetGpuWindowDims(0, &data);
+ sub_80C4C9C(0, 0);
+}
+
+static void sub_80C2C1C(u8 taskId)
+{
+ gTasks[taskId].func = sub_80C2C7C;
+}
+
+static void sub_80C2C38(void)
+{
+ sub_80C210C(0, 4, 4);
+ sub_80C210C(1, 5, 5);
+ sub_80C210C(2, 6, 6);
+ sub_80C210C(3, 7, 7);
+ sub_80C210C(4, 8, 8);
+ sub_80C210C(5, 9, 9);
+}
+
+static void sub_80C2C7C(u8 taskId)
+{
+ switch (gUnknown_20399E0->field_CCF)
+ {
+ case 0:
+ sub_80C4ED0(TRUE);
+ CopyWindowToVram(3, 3);
+ CopyWindowToVram(4, 3);
+ gUnknown_20399E0->field_CCF++;
+ break;
+ case 1:
+ sub_80C2C38();
+ gUnknown_20399E0->field_CCF++;
+ break;
+ case 2:
+ LoadPalette(gUnknown_83EF2DC, 0x00, 0xA0);
+ gUnknown_20399E0->field_CCF++;
+ break;
+ case 3:
+ sub_80C22C4(6, FALSE);
+ sub_80C4324(TRUE);
+ sub_80C3154(TRUE);
+ sub_80C4960(255, 25, TRUE);
+ sub_80C48BC(255, 25, TRUE);
+ gUnknown_20399E0->field_CCE = 0;
+ gUnknown_20399E0->field_CD0 = 0;
+ gUnknown_20399E0->field_CCF++;
+ break;
+ case 4:
+ sub_80C253C();
+ gUnknown_20399E0->field_CCF++;
+ break;
+ case 5:
+ if (gUnknown_20399E0->field_CD0 == 15)
+ {
+ sub_80C4C48(gUnknown_20399E0->field_CD0);
+ gUnknown_20399E0->field_CCF++;
+ }
+ else
+ {
+ gUnknown_20399E0->field_CD0++;
+ sub_80C4C48(gUnknown_20399E0->field_CD0);
+ }
+ break;
+ case 6:
+ sub_80C2B9C();
+ sub_80C2B48();
+ PlaySE(SE_CARD2);
+ gUnknown_20399E0->field_CCF++;
+ break;
+ case 7:
+ if (sub_80C2E1C() == TRUE)
+ gUnknown_20399E0->field_CCF++;
+ break;
+ default:
+ gTasks[taskId].func = gUnknown_20399E0->field_CC8;
+ break;
+ }
+}
+
+
+static bool8 sub_80C2E1C(void)
+{
+ sub_80C2B48();
+ if (gUnknown_20399E0->field_000[0]->field_400->pos1.x == 104)
+ {
+ return TRUE;
+ }
+ else if (gUnknown_20399E0->field_CCE > 17)
+ {
+ gUnknown_20399E0->field_000[0]->field_400->pos1.x += 1;
+ gUnknown_20399E0->field_000[1]->field_400->pos1.x += 1;
+ gUnknown_20399E0->field_000[2]->field_400->pos1.x += 1;
+ gUnknown_20399E0->field_000[3]->field_400->pos1.x -= 1;
+ gUnknown_20399E0->field_000[4]->field_400->pos1.x -= 1;
+ gUnknown_20399E0->field_000[5]->field_400->pos1.x -= 1;
+ }
+ else if (gUnknown_20399E0->field_CCE > 14)
+ {
+ gUnknown_20399E0->field_000[0]->field_400->pos1.x += 2;
+ gUnknown_20399E0->field_000[1]->field_400->pos1.x += 2;
+ gUnknown_20399E0->field_000[2]->field_400->pos1.x += 2;
+ gUnknown_20399E0->field_000[3]->field_400->pos1.x -= 2;
+ gUnknown_20399E0->field_000[4]->field_400->pos1.x -= 2;
+ gUnknown_20399E0->field_000[5]->field_400->pos1.x -= 2;
+ }
+ else if (gUnknown_20399E0->field_CCE > 10)
+ {
+ gUnknown_20399E0->field_000[0]->field_400->pos1.x += 3;
+ gUnknown_20399E0->field_000[1]->field_400->pos1.x += 3;
+ gUnknown_20399E0->field_000[2]->field_400->pos1.x += 3;
+ gUnknown_20399E0->field_000[3]->field_400->pos1.x -= 3;
+ gUnknown_20399E0->field_000[4]->field_400->pos1.x -= 3;
+ gUnknown_20399E0->field_000[5]->field_400->pos1.x -= 3;
+ }
+ else if (gUnknown_20399E0->field_CCE > 6)
+ {
+ gUnknown_20399E0->field_000[0]->field_400->pos1.x += 5;
+ gUnknown_20399E0->field_000[1]->field_400->pos1.x += 5;
+ gUnknown_20399E0->field_000[2]->field_400->pos1.x += 5;
+ gUnknown_20399E0->field_000[3]->field_400->pos1.x -= 5;
+ gUnknown_20399E0->field_000[4]->field_400->pos1.x -= 5;
+ gUnknown_20399E0->field_000[5]->field_400->pos1.x -= 5;
+ }
+ else
+ {
+ gUnknown_20399E0->field_000[0]->field_400->pos1.x += 8;
+ gUnknown_20399E0->field_000[1]->field_400->pos1.x += 8;
+ gUnknown_20399E0->field_000[2]->field_400->pos1.x += 8;
+ gUnknown_20399E0->field_000[3]->field_400->pos1.x -= 8;
+ gUnknown_20399E0->field_000[4]->field_400->pos1.x -= 8;
+ gUnknown_20399E0->field_000[5]->field_400->pos1.x -= 8;
+ }
+ gUnknown_20399E0->field_CCE++;
+ return FALSE;
+}
+
+static void sub_80C2FC0(struct Sprite * sprite)
+{
+ if (gUnknown_20399E4->field_00C != 0)
+ {
+ sprite->pos1.x += gUnknown_20399E4->field_008;
+ sprite->pos1.y += gUnknown_20399E4->field_00A;
+ gUnknown_20399E4->field_00C--;
+ }
+ else
+ {
+ gUnknown_20399E4->field_01C->pos1.x = 8 * gUnknown_20399E4->field_000 + 36;
+ gUnknown_20399E4->field_01C->pos1.y = 8 * gUnknown_20399E4->field_002 + 36;
+ }
+}
+
+static void sub_80C3008(u16 a0, u16 a1)
+{
+ gUnknown_20399E4 = AllocZeroed(sizeof(struct UnkStruct_20399E4));
+ LZ77UnCompWram(gUnknown_83EF4E0, gUnknown_20399E4->field_024);
+ gUnknown_20399E4->field_020 = a0;
+ gUnknown_20399E4->field_022 = a1;
+ GetPlayerPositionOnRegionMap_HandleOverrides();
+ gUnknown_20399E4->field_004 = 8 * gUnknown_20399E4->field_000 + 36;
+ gUnknown_20399E4->field_006 = 8 * gUnknown_20399E4->field_002 + 36;
+ gUnknown_20399E4->field_010 = sub_80C31C0;
+ gUnknown_20399E4->field_016 = sub_80C35DC(gUnknown_20399E4->field_014);
+ gUnknown_20399E4->field_018 = sub_80C3878(GetSelectedMapSection(GetWhichRegionMap(), 1, gUnknown_20399E4->field_002, gUnknown_20399E4->field_000));
+ sub_80C309C();
+}
+
+static void sub_80C309C(void)
+{
+ u8 spriteId;
+ struct SpriteSheet spriteSheet = {
+ .data = gUnknown_20399E4->field_024,
+ .size = 0x100,
+ .tag = gUnknown_20399E4->field_020
+ };
+ struct SpritePalette spritePalette = {
+ .data = gUnknown_83EF25C,
+ .tag = gUnknown_20399E4->field_022
+ };
+ struct SpriteTemplate template = {
+ .tileTag = gUnknown_20399E4->field_020,
+ .paletteTag = gUnknown_20399E4->field_022,
+ .oam = &gUnknown_83F1C3C,
+ .anims = gUnknown_83F1C50,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80C2FC0
+ };
+
+ LoadSpriteSheet(&spriteSheet);
+ LoadSpritePalette(&spritePalette);
+ spriteId = CreateSprite(&template, gUnknown_20399E4->field_004, gUnknown_20399E4->field_006, 0);
+ gUnknown_20399E4->field_01C = &gSprites[spriteId];
+ sub_80C3154(TRUE);
+}
+
+static void sub_80C3154(bool8 a0)
+{
+ gUnknown_20399E4->field_01C->invisible = a0;
+}
+
+static void sub_80C3178(void)
+{
+ gUnknown_20399E4->field_00E = 0;
+}
+
+static void sub_80C3188(void)
+{
+ if (gUnknown_20399E4->field_01C != NULL)
+ {
+ DestroySprite(gUnknown_20399E4->field_01C);
+ FreeSpriteTilesByTag(gUnknown_20399E4->field_020);
+ FreeSpritePaletteByTag(gUnknown_20399E4->field_022);
+ }
+ FREE_IF_NOT_NULL(gUnknown_20399E4);
+}
+
+static u8 sub_80C31C0(void)
+{
+ u8 ret = 0;
+ gUnknown_20399E4->field_008 = 0;
+ gUnknown_20399E4->field_00A = 0;
+
+ if (JOY_HELD(DPAD_UP))
+ {
+ if (gUnknown_20399E4->field_002 > 0)
+ {
+ gUnknown_20399E4->field_00A = -2;
+ ret = 1;
+ }
+ }
+ if (JOY_HELD(DPAD_DOWN))
+ {
+ if (gUnknown_20399E4->field_002 < 14)
+ {
+ gUnknown_20399E4->field_00A = 2;
+ ret = 1;
+ }
+ }
+ if (JOY_HELD(DPAD_RIGHT))
+ {
+ if (gUnknown_20399E4->field_000 < 21)
+ {
+ gUnknown_20399E4->field_008 = 2;
+ ret = 1;
+ }
+ }
+ if (JOY_HELD(DPAD_LEFT))
+ {
+ if (gUnknown_20399E4->field_000 > 0)
+ {
+ gUnknown_20399E4->field_008 = -2;
+ ret = 1;
+ }
+ }
+ if (JOY_NEW(A_BUTTON))
+ {
+ ret = 4;
+ if (gUnknown_20399E4->field_000 == 21 && gUnknown_20399E4->field_002 == 13)
+ {
+ PlaySE(SE_W063B);
+ ret = 6;
+ }
+ if (gUnknown_20399E4->field_000 == 21 && gUnknown_20399E4->field_002 == 11)
+ {
+ if (GetRegionMapPermission(MAPPERM_0) == TRUE)
+ {
+ PlaySE(SE_W063B);
+ ret = 5;
+ }
+ }
+ }
+ else if (!JOY_NEW(B_BUTTON))
+ {
+ if (JOY_REPT(START_BUTTON))
+ {
+ sub_80C3418();
+ gUnknown_20399E4->field_014 = GetSelectedMapSection(GetWhichRegionMap(), 0, gUnknown_20399E4->field_002, gUnknown_20399E4->field_000);
+ gUnknown_20399E4->field_016 = sub_80C35DC(gUnknown_20399E4->field_014);
+ gUnknown_20399E4->field_018 = sub_80C3878(GetSelectedMapSection(GetWhichRegionMap(), 1, gUnknown_20399E4->field_002, gUnknown_20399E4->field_000));
+ return 3;
+ }
+ else if (JOY_NEW(SELECT_BUTTON) && gUnknown_20399D4->savedCallback == CB2_ReturnToField)
+ {
+ ret = 6;
+ }
+ }
+ else
+ {
+ ret = 6;
+ }
+ if (ret == 1)
+ {
+ gUnknown_20399E4->field_00C = 4;
+ gUnknown_20399E4->field_010 = sub_80C3348;
+ }
+ return ret;
+}
+
+static u8 sub_80C3348(void)
+{
+ if (gUnknown_20399E4->field_00C != 0)
+ return 2;
+ if (gUnknown_20399E4->field_008 > 0)
+ gUnknown_20399E4->field_000++;
+ if (gUnknown_20399E4->field_008 < 0)
+ gUnknown_20399E4->field_000--;
+ if (gUnknown_20399E4->field_00A > 0)
+ gUnknown_20399E4->field_002++;
+ if (gUnknown_20399E4->field_00A < 0)
+ gUnknown_20399E4->field_002--;
+ gUnknown_20399E4->field_014 = GetSelectedMapSection(GetWhichRegionMap(), 0, gUnknown_20399E4->field_002, gUnknown_20399E4->field_000);
+ gUnknown_20399E4->field_016 = sub_80C35DC(gUnknown_20399E4->field_014);
+ gUnknown_20399E4->field_018 = sub_80C3878(GetSelectedMapSection(GetWhichRegionMap(), 1, gUnknown_20399E4->field_002, gUnknown_20399E4->field_000));
+ gUnknown_20399E4->field_010 = sub_80C31C0;
+ return 3;
+}
+
+static u8 sub_80C3400(void)
+{
+ return gUnknown_20399E4->field_010();
+}
+
+static void sub_80C3418(void)
+{
+ if (GetRegionMapPermission(MAPPERM_0) == 1)
+ {
+ gUnknown_20399E4->field_00E++;
+ gUnknown_20399E4->field_00E %= 3;
+ if (gUnknown_20399E4->field_00E == 0 && GetWhichRegionMap() != sub_80C0E34())
+ {
+ gUnknown_20399E4->field_00E++;
+ }
+ switch (gUnknown_20399E4->field_00E)
+ {
+ case 0:
+ default:
+ gUnknown_20399E4->field_000 = sub_80C4380();
+ gUnknown_20399E4->field_002 = sub_80C438C();
+ break;
+ case 1:
+ gUnknown_20399E4->field_000 = 21;
+ gUnknown_20399E4->field_002 = 11;
+ break;
+ case 2:
+ gUnknown_20399E4->field_002 = 13;
+ gUnknown_20399E4->field_000 = 21;
+ break;
+ }
+ }
+ else
+ {
+ gUnknown_20399E4->field_00E++;
+ gUnknown_20399E4->field_00E %= 2;
+ switch (gUnknown_20399E4->field_00E)
+ {
+ case 0:
+ default:
+ gUnknown_20399E4->field_000 = sub_80C4380();
+ gUnknown_20399E4->field_002 = sub_80C438C();
+ break;
+ case 1:
+ gUnknown_20399E4->field_002 = 13;
+ gUnknown_20399E4->field_000 = 21;
+ break;
+ }
+ }
+ gUnknown_20399E4->field_01C->pos1.x = 8 * gUnknown_20399E4->field_000 + 36;
+ gUnknown_20399E4->field_01C->pos1.y = 8 * gUnknown_20399E4->field_002 + 36;
+ gUnknown_20399E4->field_014 = GetSelectedMapSection(GetWhichRegionMap(), 0, gUnknown_20399E4->field_002, gUnknown_20399E4->field_000);
+}
+
+static u16 GetMapCursorX(void)
+{
+ return gUnknown_20399E4->field_000;
+}
+
+static u16 GetMapCursorY(void)
+{
+ return gUnknown_20399E4->field_002;
+}
+
+static u16 sub_80C3520(void)
+{
+ u8 ret;
+ if (gUnknown_20399E4->field_002 < 0
+ || gUnknown_20399E4->field_002 > 14
+ || gUnknown_20399E4->field_000 < 0
+ || gUnknown_20399E4->field_000 > 21)
+ return MAPSEC_NONE;
+
+ ret = GetSelectedMapSection(GetWhichRegionMap(), 0, gUnknown_20399E4->field_002, gUnknown_20399E4->field_000);
+ if ((ret == MAPSEC_NAVEL_ROCK || ret == MAPSEC_BIRTH_ISLAND) && !FlagGet(FLAG_WORLD_MAP_NAVEL_ROCK_EXTERIOR))
+ ret = MAPSEC_NONE;
+ return ret;
+}
+
+static u16 GetMapSecUnderCursor(void)
+{
+ u8 ret;
+ if (gUnknown_20399E4->field_002 < 0
+ || gUnknown_20399E4->field_002 > 14
+ || gUnknown_20399E4->field_000 < 0
+ || gUnknown_20399E4->field_000 > 21)
+ return MAPSEC_NONE;
+
+ ret = GetSelectedMapSection(GetWhichRegionMap(), 1, gUnknown_20399E4->field_002, gUnknown_20399E4->field_000);
+ if (ret == MAPSEC_CERULEAN_CAVE && !FlagGet(FLAG_SYS_CAN_LINK_WITH_RS))
+ ret = MAPSEC_NONE;
+ return ret;
+}
+
+static u8 sub_80C35DC(u8 mapsec)
+{
+ switch (mapsec)
+ {
+ case MAPSEC_PALLET_TOWN:
+ return FlagGet(FLAG_WORLD_MAP_PALLET_TOWN) ? 2 : 3;
+ case MAPSEC_VIRIDIAN_CITY:
+ return FlagGet(FLAG_WORLD_MAP_VIRIDIAN_CITY) ? 2 : 3;
+ case MAPSEC_PEWTER_CITY:
+ return FlagGet(FLAG_WORLD_MAP_PEWTER_CITY) ? 2 : 3;
+ case MAPSEC_CERULEAN_CITY:
+ return FlagGet(FLAG_WORLD_MAP_CERULEAN_CITY) ? 2 : 3;
+ case MAPSEC_LAVENDER_TOWN:
+ return FlagGet(FLAG_WORLD_MAP_LAVENDER_TOWN) ? 2 : 3;
+ case MAPSEC_VERMILION_CITY:
+ return FlagGet(FLAG_WORLD_MAP_VERMILION_CITY) ? 2 : 3;
+ case MAPSEC_CELADON_CITY:
+ return FlagGet(FLAG_WORLD_MAP_CELADON_CITY) ? 2 : 3;
+ case MAPSEC_FUCHSIA_CITY:
+ return FlagGet(FLAG_WORLD_MAP_FUCHSIA_CITY) ? 2 : 3;
+ case MAPSEC_CINNABAR_ISLAND:
+ return FlagGet(FLAG_WORLD_MAP_CINNABAR_ISLAND) ? 2 : 3;
+ case MAPSEC_INDIGO_PLATEAU:
+ return FlagGet(FLAG_WORLD_MAP_INDIGO_PLATEAU_EXTERIOR) ? 2 : 3;
+ case MAPSEC_SAFFRON_CITY:
+ return FlagGet(FLAG_WORLD_MAP_SAFFRON_CITY) ? 2 : 3;
+ case MAPSEC_ONE_ISLAND:
+ return FlagGet(FLAG_WORLD_MAP_ONE_ISLAND) ? 2 : 3;
+ case MAPSEC_TWO_ISLAND:
+ return FlagGet(FLAG_WORLD_MAP_TWO_ISLAND) ? 2 : 3;
+ case MAPSEC_THREE_ISLAND:
+ return FlagGet(FLAG_WORLD_MAP_THREE_ISLAND) ? 2 : 3;
+ case MAPSEC_FOUR_ISLAND:
+ return FlagGet(FLAG_WORLD_MAP_FOUR_ISLAND) ? 2 : 3;
+ case MAPSEC_FIVE_ISLAND:
+ return FlagGet(FLAG_WORLD_MAP_FIVE_ISLAND) ? 2 : 3;
+ case MAPSEC_SEVEN_ISLAND:
+ return FlagGet(FLAG_WORLD_MAP_SEVEN_ISLAND) ? 2 : 3;
+ case MAPSEC_SIX_ISLAND:
+ return FlagGet(FLAG_WORLD_MAP_SIX_ISLAND) ? 2 : 3;
+ case MAPSEC_ROUTE_4_FLYDUP:
+ if (!GetRegionMapPermission(MAPPERM_3))
+ return 0;
+ return FlagGet(FLAG_WORLD_MAP_ROUTE4_POKEMON_CENTER_1F) ? 2 : 3;
+ case MAPSEC_ROUTE_10_FLYDUP:
+ return FlagGet(FLAG_WORLD_MAP_ROUTE10_POKEMON_CENTER_1F) ? 2 : 3;
+ case MAPSEC_NONE:
+ return 0;
+ default:
+ return 1;
+ }
+}
+
+static u8 sub_80C3878(u8 mapsec)
+{
+ switch (mapsec)
+ {
+ case MAPSEC_NONE:
+ return 0;
+ case MAPSEC_VIRIDIAN_FOREST:
+ return FlagGet(FLAG_WORLD_MAP_VIRIDIAN_FOREST) ? 2 : 3;
+ case MAPSEC_MT_MOON:
+ return FlagGet(FLAG_WORLD_MAP_MT_MOON_1F) ? 2 : 3;
+ case MAPSEC_S_S_ANNE:
+ return FlagGet(FLAG_WORLD_MAP_SSANNE_EXTERIOR) ? 2 : 3;
+ case MAPSEC_UNDERGROUND_PATH:
+ return FlagGet(FLAG_WORLD_MAP_UNDERGROUND_PATH_NORTH_SOUTH_TUNNEL) ? 2 : 3;
+ case MAPSEC_UNDERGROUND_PATH_2:
+ return FlagGet(FLAG_WORLD_MAP_UNDERGROUND_PATH_EAST_WEST_TUNNEL) ? 2 : 3;
+ case MAPSEC_DIGLETTS_CAVE:
+ return FlagGet(FLAG_WORLD_MAP_DIGLETTS_CAVE_B1F) ? 2 : 3;
+ case MAPSEC_KANTO_VICTORY_ROAD:
+ return FlagGet(FLAG_WORLD_MAP_VICTORY_ROAD_1F) ? 2 : 3;
+ case MAPSEC_ROCKET_HIDEOUT:
+ return FlagGet(FLAG_WORLD_MAP_ROCKET_HIDEOUT_B1F) ? 2 : 3;
+ case MAPSEC_SILPH_CO:
+ return FlagGet(FLAG_WORLD_MAP_SILPH_CO_1F) ? 2 : 3;
+ case MAPSEC_POKEMON_MANSION:
+ return FlagGet(FLAG_WORLD_MAP_POKEMON_MANSION_1F) ? 2 : 3;
+ case MAPSEC_KANTO_SAFARI_ZONE:
+ return FlagGet(FLAG_WORLD_MAP_SAFARI_ZONE_CENTER) ? 2 : 3;
+ case MAPSEC_POKEMON_LEAGUE:
+ return FlagGet(FLAG_WORLD_MAP_POKEMON_LEAGUE_LORELEIS_ROOM) ? 2 : 3;
+ case MAPSEC_ROCK_TUNNEL:
+ return FlagGet(FLAG_WORLD_MAP_ROCK_TUNNEL_1F) ? 2 : 3;
+ case MAPSEC_SEAFOAM_ISLANDS:
+ return FlagGet(FLAG_WORLD_MAP_SEAFOAM_ISLANDS_1F) ? 2 : 3;
+ case MAPSEC_POKEMON_TOWER:
+ return FlagGet(FLAG_WORLD_MAP_POKEMON_TOWER_1F) ? 2 : 3;
+ case MAPSEC_CERULEAN_CAVE:
+ return FlagGet(FLAG_WORLD_MAP_CERULEAN_CAVE_1F) ? 2 : 3;
+ case MAPSEC_POWER_PLANT:
+ return FlagGet(FLAG_WORLD_MAP_POWER_PLANT) ? 2 : 3;
+ case MAPSEC_NAVEL_ROCK:
+ return FlagGet(FLAG_WORLD_MAP_NAVEL_ROCK_EXTERIOR) ? 2 : 3;
+ case MAPSEC_MT_EMBER:
+ return FlagGet(FLAG_WORLD_MAP_MT_EMBER_EXTERIOR) ? 2 : 3;
+ case MAPSEC_BERRY_FOREST:
+ return FlagGet(FLAG_WORLD_MAP_THREE_ISLAND_BERRY_FOREST) ? 2 : 3;
+ case MAPSEC_ICEFALL_CAVE:
+ return FlagGet(FLAG_WORLD_MAP_FOUR_ISLAND_ICEFALL_CAVE_ENTRANCE) ? 2 : 3;
+ case MAPSEC_ROCKET_WAREHOUSE:
+ return FlagGet(FLAG_WORLD_MAP_FIVE_ISLAND_ROCKET_WAREHOUSE) ? 2 : 3;
+ case MAPSEC_TRAINER_TOWER_2:
+ return FlagGet(FLAG_WORLD_MAP_SEVEN_ISLAND_TRAINER_TOWER_LOBBY) ? 2 : 3;
+ case MAPSEC_DOTTED_HOLE:
+ return FlagGet(FLAG_WORLD_MAP_SIX_ISLAND_DOTTED_HOLE_1F) ? 2 : 3;
+ case MAPSEC_LOST_CAVE:
+ return FlagGet(FLAG_WORLD_MAP_FIVE_ISLAND_LOST_CAVE_ENTRANCE) ? 2 : 3;
+ case MAPSEC_PATTERN_BUSH:
+ return FlagGet(FLAG_WORLD_MAP_SIX_ISLAND_PATTERN_BUSH) ? 2 : 3;
+ case MAPSEC_ALTERING_CAVE:
+ return FlagGet(FLAG_WORLD_MAP_SIX_ISLAND_ALTERING_CAVE) ? 2 : 3;
+ case MAPSEC_TANOBY_CHAMBERS:
+ return FlagGet(FLAG_WORLD_MAP_SEVEN_ISLAND_TANOBY_RUINS_MONEAN_CHAMBER) ? 2 : 3;
+ case MAPSEC_THREE_ISLE_PATH:
+ return FlagGet(FLAG_WORLD_MAP_THREE_ISLAND_DUNSPARCE_TUNNEL) ? 2 : 3;
+ case MAPSEC_TANOBY_KEY:
+ return FlagGet(FLAG_WORLD_MAP_SEVEN_ISLAND_SEVAULT_CANYON_TANOBY_KEY) ? 2 : 3;
+ case MAPSEC_BIRTH_ISLAND:
+ return FlagGet(FLAG_WORLD_MAP_BIRTH_ISLAND_EXTERIOR) ? 2 : 3;
+ default:
+ return 1;
+ }
+}
+
+static u8 sub_80C3AC8(u8 a0)
+{
+ switch (a0)
+ {
+ default:
+ return gUnknown_20399E4->field_016;
+ case 0:
+ return gUnknown_20399E4->field_016;
+ case 1:
+ return gUnknown_20399E4->field_018;
+ }
+}
+
+static u16 GetPlayerCurrentMapSectionId(void)
+{
+ return Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum)->regionMapSectionId;
+}
+
+static void GetPlayerPositionOnRegionMap(void)
+{
+ u16 width;
+ u32 divisor;
+ u16 height;
+ u16 x;
+ u16 y;
+ u32 r6;
+ const struct MapHeader * mapHeader;
+ struct WarpData * warp;
+
+ switch (get_map_light_level_by_bank_and_number(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum))
+ {
+ default:
+ case 1:
+ case 2:
+ case 3:
+ case 5:
+ case 6:
+ gUnknown_20399E4->field_014 = gMapHeader.regionMapSectionId;
+ width = gMapHeader.mapLayout->width;
+ height = gMapHeader.mapLayout->height;
+ x = gSaveBlock1Ptr->pos.x;
+ y = gSaveBlock1Ptr->pos.y;
+ break;
+ case 4:
+ case 7:
+ mapHeader = Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->escapeWarp.mapGroup, gSaveBlock1Ptr->escapeWarp.mapNum);
+ gUnknown_20399E4->field_014 = mapHeader->regionMapSectionId;
+ width = mapHeader->mapLayout->width;
+ height = mapHeader->mapLayout->height;
+ x = gSaveBlock1Ptr->escapeWarp.x;
+ y = gSaveBlock1Ptr->escapeWarp.y;
+ break;
+ case 9:
+ mapHeader = Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->warp2.mapGroup, gSaveBlock1Ptr->warp2.mapNum);
+ gUnknown_20399E4->field_014 = mapHeader->regionMapSectionId;
+ width = mapHeader->mapLayout->width;
+ height = mapHeader->mapLayout->height;
+ x = gSaveBlock1Ptr->warp2.x;
+ y = gSaveBlock1Ptr->warp2.y;
+ break;
+ case 8:
+ if ((gUnknown_20399E4->field_014 = gMapHeader.regionMapSectionId) != MAPSEC_SPECIAL_AREA)
+ {
+ warp = &gSaveBlock1Ptr->escapeWarp;
+ mapHeader = Overworld_GetMapHeaderByGroupAndId(warp->mapGroup, warp->mapNum);
+ }
+ else
+ {
+ warp = &gSaveBlock1Ptr->warp2;
+ mapHeader = Overworld_GetMapHeaderByGroupAndId(warp->mapGroup, warp->mapNum);
+ gUnknown_20399E4->field_014 = mapHeader->regionMapSectionId;
+ }
+ width = mapHeader->mapLayout->width;
+ height = mapHeader->mapLayout->height;
+ x = warp->x;
+ y = warp->y;
+ break;
+ }
+
+ gUnknown_20399E4->field_014 -= MAPSECS_KANTO;
+ divisor = width / sMapSectionDimensions[gUnknown_20399E4->field_014][0];
+ if (divisor == 0)
+ divisor = 1;
+ x /= divisor;
+ if (x >= sMapSectionDimensions[gUnknown_20399E4->field_014][0])
+ x = sMapSectionDimensions[gUnknown_20399E4->field_014][0] - 1;
+ divisor = height / sMapSectionDimensions[gUnknown_20399E4->field_014][1];
+ if (divisor == 0)
+ divisor = 1;
+ y /= divisor;
+ if (y >= sMapSectionDimensions[gUnknown_20399E4->field_014][1])
+ y = sMapSectionDimensions[gUnknown_20399E4->field_014][1] - 1;
+ gUnknown_20399E4->field_000 = x + sMapSectionTopLeftCorners[gUnknown_20399E4->field_014][0];
+ gUnknown_20399E4->field_002 = y + sMapSectionTopLeftCorners[gUnknown_20399E4->field_014][1];
+}
+
+static void GetPlayerPositionOnRegionMap_HandleOverrides(void)
+{
+ switch (GetPlayerCurrentMapSectionId())
+ {
+ case MAPSEC_KANTO_SAFARI_ZONE:
+ gUnknown_20399E4->field_000 = 12;
+ gUnknown_20399E4->field_002 = 12;
+ break;
+ case MAPSEC_SILPH_CO:
+ gUnknown_20399E4->field_000 = 14;
+ gUnknown_20399E4->field_002 = 6;
+ break;
+ case MAPSEC_POKEMON_MANSION:
+ gUnknown_20399E4->field_000 = 4;
+ gUnknown_20399E4->field_002 = 14;
+ break;
+ case MAPSEC_POKEMON_TOWER:
+ gUnknown_20399E4->field_000 = 18;
+ gUnknown_20399E4->field_002 = 6;
+ break;
+ case MAPSEC_POWER_PLANT:
+ gUnknown_20399E4->field_000 = 18;
+ gUnknown_20399E4->field_002 = 4;
+ break;
+ case MAPSEC_S_S_ANNE:
+ gUnknown_20399E4->field_000 = 14;
+ gUnknown_20399E4->field_002 = 9;
+ break;
+ case MAPSEC_POKEMON_LEAGUE:
+ gUnknown_20399E4->field_000 = 2;
+ gUnknown_20399E4->field_002 = 3;
+ break;
+ case MAPSEC_ROCKET_HIDEOUT:
+ gUnknown_20399E4->field_000 = 11;
+ gUnknown_20399E4->field_002 = 6;
+ break;
+ case MAPSEC_UNDERGROUND_PATH:
+ gUnknown_20399E4->field_000 = 14;
+ gUnknown_20399E4->field_002 = 7;
+ if (gSaveBlock1Ptr->location.mapNum == MAP_NUM(UNDERGROUND_PATH_NORTH_ENTRANCE))
+ {
+ gUnknown_20399E4->field_000 = 14; // optimized out but required to match
+ gUnknown_20399E4->field_002 = 5;
+ }
+ break;
+ case MAPSEC_UNDERGROUND_PATH_2:
+ gUnknown_20399E4->field_000 = 12;
+ gUnknown_20399E4->field_002 = 6;
+ if (gSaveBlock1Ptr->location.mapNum == MAP_NUM(UNDERGROUND_PATH_EAST_ENTRANCE))
+ {
+ gUnknown_20399E4->field_000 = 15;
+ gUnknown_20399E4->field_002 = 6; // optimized out but required to match
+ }
+ break;
+ case MAPSEC_BIRTH_ISLAND:
+ gUnknown_20399E4->field_000 = 18;
+ gUnknown_20399E4->field_002 = 13;
+ break;
+ case MAPSEC_NAVEL_ROCK:
+ gUnknown_20399E4->field_000 = 10;
+ gUnknown_20399E4->field_002 = 8;
+ break;
+ case MAPSEC_TRAINER_TOWER_2:
+ gUnknown_20399E4->field_000 = 5;
+ gUnknown_20399E4->field_002 = 6;
+ break;
+ case MAPSEC_MT_EMBER:
+ gUnknown_20399E4->field_000 = 2;
+ gUnknown_20399E4->field_002 = 3;
+ break;
+ case MAPSEC_BERRY_FOREST:
+ gUnknown_20399E4->field_000 = 14;
+ gUnknown_20399E4->field_002 = 12;
+ break;
+ case MAPSEC_PATTERN_BUSH:
+ gUnknown_20399E4->field_000 = 17;
+ gUnknown_20399E4->field_002 = 3;
+ break;
+ case MAPSEC_ROCKET_WAREHOUSE:
+ gUnknown_20399E4->field_000 = 17;
+ gUnknown_20399E4->field_002 = 11;
+ break;
+ case MAPSEC_DILFORD_CHAMBER:
+ case MAPSEC_LIPTOO_CHAMBER:
+ case MAPSEC_MONEAN_CHAMBER:
+ case MAPSEC_RIXY_CHAMBER:
+ case MAPSEC_SCUFIB_CHAMBER:
+ case MAPSEC_TANOBY_CHAMBERS:
+ case MAPSEC_VIAPOIS_CHAMBER:
+ case MAPSEC_WEEPTH_CHAMBER:
+ gUnknown_20399E4->field_000 = 9;
+ gUnknown_20399E4->field_002 = 12;
+ break;
+ case MAPSEC_DOTTED_HOLE:
+ gUnknown_20399E4->field_000 = 16;
+ gUnknown_20399E4->field_002 = 8;
+ break;
+ case MAPSEC_VIRIDIAN_FOREST:
+ gUnknown_20399E4->field_000 = 4;
+ gUnknown_20399E4->field_002 = 6;
+ break;
+ case MAPSEC_ROUTE_2:
+ if (gSaveBlock1Ptr->location.mapNum == MAP_NUM(PALLET_TOWN))
+ {
+ gUnknown_20399E4->field_000 = 4;
+ gUnknown_20399E4->field_002 = 7;
+ }
+ else if (gSaveBlock1Ptr->location.mapNum == MAP_NUM(CERULEAN_CITY))
+ {
+ gUnknown_20399E4->field_000 = 4;
+ gUnknown_20399E4->field_002 = 5;
+ }
+ else
+ {
+ GetPlayerPositionOnRegionMap();
+ }
+ break;
+ case MAPSEC_ROUTE_21:
+ if (gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE21_NORTH))
+ {
+ gUnknown_20399E4->field_000 = 4;
+ gUnknown_20399E4->field_002 = 12;
+ }
+ else if (gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE21_SOUTH))
+ {
+ gUnknown_20399E4->field_000 = 4;
+ gUnknown_20399E4->field_002 = 13;
+ }
+ break;
+ case MAPSEC_ROUTE_5:
+ if (gSaveBlock1Ptr->location.mapNum == MAP_NUM(VIRIDIAN_CITY))
+ {
+ gUnknown_20399E4->field_000 = 14;
+ gUnknown_20399E4->field_002 = 5;
+ }
+ else
+ {
+ GetPlayerPositionOnRegionMap();
+ }
+ break;
+ case MAPSEC_ROUTE_6:
+ if (gSaveBlock1Ptr->location.mapNum == MAP_NUM(PALLET_TOWN))
+ {
+ gUnknown_20399E4->field_000 = 14;
+ gUnknown_20399E4->field_002 = 7;
+ }
+ else
+ {
+ GetPlayerPositionOnRegionMap();
+ }
+ break;
+ case MAPSEC_ROUTE_7:
+ if (gSaveBlock1Ptr->location.mapNum == MAP_NUM(PALLET_TOWN))
+ {
+ gUnknown_20399E4->field_000 = 13;
+ gUnknown_20399E4->field_002 = 6;
+ }
+ else
+ {
+ GetPlayerPositionOnRegionMap();
+ }
+ break;
+ case MAPSEC_ROUTE_8:
+ if (gSaveBlock1Ptr->location.mapNum == MAP_NUM(PALLET_TOWN))
+ {
+ gUnknown_20399E4->field_000 = 15;
+ gUnknown_20399E4->field_002 = 6;
+ }
+ else
+ {
+ GetPlayerPositionOnRegionMap();
+ }
+ break;
+ default:
+ GetPlayerPositionOnRegionMap();
+ break;
+ }
+ gUnknown_20399E4->field_014 = GetSelectedMapSection(GetWhichRegionMap(), 0, gUnknown_20399E4->field_002, gUnknown_20399E4->field_000);
+}
+
+static u8 GetSelectedMapSection(u8 whichMap, u8 layer, s16 y, s16 x)
+{
+ switch (whichMap)
+ {
+ case 0:
+ return sRegionMapSections_Kanto[layer][y][x];
+ case 1:
+ return sRegionMapSections_Sevii123[layer][y][x];
+ case 2:
+ return sRegionMapSections_Sevii45[layer][y][x];
+ case 3:
+ return sRegionMapSections_Sevii67[layer][y][x];
+ default:
+ return MAPSEC_NONE;
+ }
+}
+
+static void sub_80C41D8(u16 a0, u16 a1)
+{
+ gUnknown_20399E8 = AllocZeroed(sizeof(struct UnkStruct_20399E8));
+ if (gSaveBlock2Ptr->playerGender == FEMALE)
+ LZ77UnCompWram(gUnknown_83EF59C, gUnknown_20399E8->field_0C);
+ else
+ LZ77UnCompWram(gUnknown_83EF524, gUnknown_20399E8->field_0C);
+ gUnknown_20399E8->field_08 = a0;
+ gUnknown_20399E8->field_0A = a1;
+ gUnknown_20399E8->field_00 = GetMapCursorX();
+ gUnknown_20399E8->field_02 = GetMapCursorY();
+ sub_80C4244();
+}
+
+static void sub_80C4244(void)
+{
+ u8 spriteId;
+ struct SpriteSheet spriteSheet = {
+ .data = gUnknown_20399E8->field_0C,
+ .size = 0x80,
+ .tag = gUnknown_20399E8->field_08
+ };
+ struct SpritePalette spritePalette = {
+ .data = gUnknown_83EF27C,
+ .tag = gUnknown_20399E8->field_0A
+ };
+ struct SpriteTemplate template = {
+ .tileTag = gUnknown_20399E8->field_08,
+ .paletteTag = gUnknown_20399E8->field_0A,
+ .oam = &gUnknown_83F1C54,
+ .anims = gUnknown_83F1C64,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy
+ };
+
+ if (gSaveBlock2Ptr->playerGender == FEMALE)
+ spritePalette.data = gUnknown_83EF29C;
+
+ LoadSpriteSheet(&spriteSheet);
+ LoadSpritePalette(&spritePalette);
+ spriteId = CreateSprite(&template, 8 * gUnknown_20399E8->field_00 + 36, 8 * gUnknown_20399E8->field_02 + 36, 2);
+ gUnknown_20399E8->field_04 = &gSprites[spriteId];
+ sub_80C4324(TRUE);
+}
+
+static void sub_80C4324(bool8 a0)
+{
+ gUnknown_20399E8->field_04->invisible = a0;
+}
+
+static void sub_80C4348(void)
+{
+ if (gUnknown_20399E8->field_04 != NULL)
+ {
+ DestroySprite(gUnknown_20399E8->field_04);
+ FreeSpriteTilesByTag(gUnknown_20399E8->field_08);
+ FreeSpritePaletteByTag(gUnknown_20399E8->field_0A);
+ }
+ FREE_IF_NOT_NULL(gUnknown_20399E8);
+}
+
+static u16 sub_80C4380(void)
+{
+ return gUnknown_20399E8->field_00;
+}
+
+static u16 sub_80C438C(void)
+{
+ return gUnknown_20399E8->field_02;
+}
+
+static void sub_80C4398(u8 a0, u8 taskId, TaskFunc taskFunc)
+{
+ gUnknown_20399EC = AllocZeroed(sizeof(struct UnkStruct_20399EC));
+ gUnknown_20399EC->field_468 = taskFunc;
+ gUnknown_20399EC->field_460 = a0;
+ LZ77UnCompWram(gUnknown_83F18D8, gUnknown_20399EC->field_000);
+ LZ77UnCompWram(gUnknown_83F1908, gUnknown_20399EC->field_040);
+ gTasks[taskId].func = sub_80C440C;
+}
+
+static void sub_80C440C(u8 taskId)
+{
+ switch (gUnknown_20399EC->field_463)
+ {
+ case 0:
+ NullVBlankHBlankCallbacks();
+ gUnknown_20399EC->field_463++;
+ break;
+ case 1:
+ sub_80C47F0();
+ gUnknown_20399EC->field_463++;
+ break;
+ case 2:
+ sub_80C4750();
+ gUnknown_20399EC->field_463++;
+ break;
+ case 3:
+ BlendPalettes(0xFFFFFFFF, 16, RGB_BLACK);
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
+ gUnknown_20399EC->field_463++;
+ break;
+ case 4:
+ sub_80C08F4();
+ gUnknown_20399EC->field_463++;
+ break;
+ default:
+ SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) | DISPCNT_OBJ_ON);
+ sub_80C44E4(taskId);
+ break;
+ }
+}
+
+static void sub_80C44E4(u8 taskId)
+{
+ gTasks[taskId].func = gUnknown_20399EC->field_468;
+}
+
+static void sub_80C450C(u8 a0, u8 a1, u16 a2, u16 a3, u8 a4, u8 a5)
+{
+ u8 spriteId;
+ struct SpriteSheet spriteSheet = {
+ .data = gUnknown_20399EC->field_040,
+ .size = 0x100,
+ .tag = a4
+ };
+ struct SpritePalette spritePalette = {
+ .data = gUnknown_83EF2BC,
+ .tag = a5
+ };
+ struct SpriteTemplate template = {
+ .tileTag = a4,
+ .paletteTag = a5,
+ .oam = &gUnknown_83F1C68,
+ .anims = gUnknown_83F1C94,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy
+ };
+
+ LoadSpriteSheet(&spriteSheet);
+ LoadSpritePalette(&spritePalette);
+ spriteId = CreateSprite(&template, 8 * a2 + 36, 8 * a3 + 36, 1);
+ gUnknown_20399EC->field_2D0[a1].field_8 = &gSprites[spriteId];
+ gSprites[spriteId].invisible = TRUE;
+ gUnknown_20399EC->field_2D0[a1].field_4 = a0;
+}
+
+static void sub_80C4614(u8 a0, u8 a1, u16 a2, u16 a3, u8 a4, u8 a5)
+{
+ u8 spriteId;
+ u8 r4;
+ s16 r7 = 0;
+ struct SpriteSheet spriteSheet = {
+ .data = gUnknown_20399EC->field_000,
+ .size = 0x40,
+ .tag = a4
+ };
+ struct SpritePalette spritePalette = {
+ .data = gUnknown_83EF2BC,
+ .tag = a5
+ };
+ struct SpriteTemplate template = {
+ .tileTag = a4,
+ .paletteTag = a5,
+ .oam = &gUnknown_83F1C70,
+ .anims = gUnknown_83F1C98,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy
+ };
+
+ LoadSpriteSheet(&spriteSheet);
+ LoadSpritePalette(&spritePalette);
+ r4 = GetSelectedMapSection(a0, 0, a3, a2);
+ if ((sub_80C35DC(r4) == 2 || sub_80C35DC(r4) == 3) && r4 != MAPSEC_ROUTE_10_FLYDUP)
+ r7 = 2;
+ spriteId = CreateSprite(&template, 8 * a2 + 36 + r7, 8 * a3 + 36 + r7, 3);
+ gUnknown_20399EC->field_140[a1].field_8 = &gSprites[spriteId];
+ gSprites[spriteId].invisible = TRUE;
+ gUnknown_20399EC->field_140[a1].field_4 = a0;
+}
+
+static void sub_80C4750(void)
+{
+ u16 i, j, k;
+ u8 r7 = 0;
+ if (GetRegionMapPermission(MAPPERM_3))
+ {
+ for (i = 0; i < 4; i++)
+ {
+ for (j = 0; j < 15; j++)
+ {
+ for (k = 0; k < 22; k++)
+ {
+ if (sub_80C35DC(GetSelectedMapSection(i, 0, j, k)) == 2)
+ {
+ sub_80C450C(i, r7, k, j, r7 + 10, 10);
+ r7++;
+ }
+ }
+ }
+ }
+ }
+}
+
+static void sub_80C47F0(void)
+{
+ u16 i, j, k;
+ u8 r6 = 0;
+ u8 mapsec;
+ for (i = 0; i < 4; i++)
+ {
+ for (j = 0; j < 15; j++)
+ {
+ for (k = 0; k < 22; k++)
+ {
+ mapsec = GetSelectedMapSection(i, 1, j, k);
+ if (mapsec == MAPSEC_NONE)
+ continue;
+ if (mapsec == MAPSEC_CERULEAN_CAVE && !FlagGet(FLAG_SYS_CAN_LINK_WITH_RS))
+ continue;
+ sub_80C4614(i, r6, k, j, r6 + 35, 10);
+ if (sub_80C3878(mapsec) != 2)
+ {
+ StartSpriteAnim(gUnknown_20399EC->field_140[r6].field_8, 1);
+ }
+ r6++;
+ }
+ }
+ }
+}
+
+static void sub_80C48BC(u8 a0, u8 a1, bool8 a2)
+{
+ u8 i;
+ if (a1 == 25)
+ {
+ for (i = 0; i < 25; i++)
+ {
+ if (gUnknown_20399EC->field_2D0[i].field_4 == a0 || a0 == 0xFF)
+ gUnknown_20399EC->field_2D0[i].field_8->invisible = a2;
+ }
+ }
+ else
+ {
+ if (gUnknown_20399EC->field_2D0[a1].field_4 == a0)
+ gUnknown_20399EC->field_2D0[a1].field_8->invisible = a2;
+ }
+}
+
+static void sub_80C4960(u8 a0, u8 a1, bool8 a2)
+{
+ u8 i;
+ if (a1 == 25)
+ {
+ for (i = 0; i < 25; i++)
+ {
+ if (gUnknown_20399EC->field_140[i].field_4 == a0 || a0 == 0xFF)
+ gUnknown_20399EC->field_140[i].field_8->invisible = a2;
+ }
+ }
+ else
+ {
+ if (gUnknown_20399EC->field_140[a1].field_4 != a0)
+ gUnknown_20399EC->field_140[a1].field_8->invisible = a2;
+ }
+}
+
+static void sub_80C4A04(void)
+{
+ u8 i;
+ for (i = 0; i < 25; i++)
+ {
+ if (gUnknown_20399EC->field_2D0[i].field_8 != NULL)
+ {
+ DestroySprite(gUnknown_20399EC->field_2D0[i].field_8);
+ FreeSpriteTilesByTag(gUnknown_20399EC->field_2D0[i].field_C);
+ FreeSpritePaletteByTag(gUnknown_20399EC->field_2D0[i].field_E);
+ }
+ }
+ for (i = 0; i < 25; i++)
+ {
+ if (gUnknown_20399EC->field_140[i].field_8 != NULL)
+ {
+ DestroySprite(gUnknown_20399EC->field_140[i].field_8);
+ FreeSpriteTilesByTag(gUnknown_20399EC->field_140[i].field_C);
+ FreeSpritePaletteByTag(gUnknown_20399EC->field_140[i].field_E);
+ }
+ }
+ FREE_IF_NOT_NULL(gUnknown_20399EC);
+}
+
+static bool8 sub_80C4AAC(u8 a0)
+{
+ if (gUnknown_20399F0[a0] != NULL)
+ return FALSE;
+ gUnknown_20399F0[a0] = AllocZeroed(sizeof(struct UnkStruct_20399F0));
+ gUnknown_20399F0[a0]->bldcnt = GetGpuReg(REG_OFFSET_BLDCNT);
+ gUnknown_20399F0[a0]->bldy = GetGpuReg(REG_OFFSET_BLDY);
+ gUnknown_20399F0[a0]->bldalpha = GetGpuReg(REG_OFFSET_BLDALPHA);
+ gUnknown_20399F0[a0]->winin = GetGpuReg(REG_OFFSET_WININ);
+ gUnknown_20399F0[a0]->winout = GetGpuReg(REG_OFFSET_WINOUT);
+ gUnknown_20399F0[a0]->win0h = GetGpuReg(REG_OFFSET_WIN0H);
+ gUnknown_20399F0[a0]->win1h = GetGpuReg(REG_OFFSET_WIN1H);
+ gUnknown_20399F0[a0]->win0v = GetGpuReg(REG_OFFSET_WIN0V);
+ gUnknown_20399F0[a0]->win1v = GetGpuReg(REG_OFFSET_WIN1V);
+ return TRUE;
+}
+
+static bool8 sub_80C4B30(u8 a0)
+{
+ if (gUnknown_20399F0[a0] == NULL)
+ return FALSE;
+ SetGpuReg(REG_OFFSET_BLDCNT, gUnknown_20399F0[a0]->bldcnt);
+ SetGpuReg(REG_OFFSET_BLDY, gUnknown_20399F0[a0]->bldy);
+ SetGpuReg(REG_OFFSET_BLDALPHA, gUnknown_20399F0[a0]->bldalpha);
+ SetGpuReg(REG_OFFSET_WININ, gUnknown_20399F0[a0]->winin);
+ SetGpuReg(REG_OFFSET_WINOUT, gUnknown_20399F0[a0]->winout);
+ SetGpuReg(REG_OFFSET_WIN0H, gUnknown_20399F0[a0]->win0h);
+ SetGpuReg(REG_OFFSET_WIN1H, gUnknown_20399F0[a0]->win1h);
+ SetGpuReg(REG_OFFSET_WIN0V, gUnknown_20399F0[a0]->win0v);
+ SetGpuReg(REG_OFFSET_WIN1V, gUnknown_20399F0[a0]->win1v);
+ FREE_IF_NOT_NULL(gUnknown_20399F0[a0]);
+ return TRUE;
+}
+
+static void sub_80C4BB8(void)
+{
+ u8 i;
+ for (i = 0; i < 3; i++)
+ {
+ FREE_IF_NOT_NULL(gUnknown_20399F0[i]);
+ }
+}
+
+static void sub_80C4BE4(void)
+{
+ struct GpuWindowParams data = {};
+ sub_80C4C2C(0, 0, 0);
+ sub_80C4C48(0);
+ SetGpuWindowDims(0, &data);
+ SetGpuWindowDims(1, &data);
+ sub_80C4C74(0, 0);
+ sub_80C4C9C(0, 1);
+ sub_80C4C9C(1, 1);
+}
+
+static void sub_80C4C2C(u8 a0, u16 a1, u16 a2)
+{
+ u16 regval = a0 << 8;
+ regval |= a1;
+ regval |= a2;
+ SetGpuReg(REG_OFFSET_BLDCNT, regval);
+}
+
+static void sub_80C4C48(u16 a0)
+{
+ SetGpuReg(REG_OFFSET_BLDY, a0);
+}
+
+static void sub_80C4C5C(u16 a0, u16 a1)
+{
+ u16 regval = a0 << 8;
+ regval |= a1;
+ SetGpuReg(REG_OFFSET_BLDALPHA, regval);
+}
+
+static void sub_80C4C74(u16 a0, u16 a1)
+{
+ u16 regval = a1 << 8;
+ regval |= a0;
+ SetGpuReg(REG_OFFSET_WININ, regval);
+}
+
+static void sub_80C4C88(u16 a0)
+{
+ SetGpuReg(REG_OFFSET_WINOUT, a0);
+}
+
+static void sub_80C4C9C(u8 a0, u8 a1)
+{
+ u16 data[2];
+ memcpy(data, sWinFlags, 4);
+ switch (a1)
+ {
+ case 0:
+ SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) | data[a0]);
+ break;
+ case 1:
+ ClearGpuRegBits(REG_OFFSET_DISPCNT, data[a0]);
+ break;
+ }
+}
+
+static void SetGpuWindowDims(u8 winIdx, const struct GpuWindowParams *data)
+{
+ SetGpuReg(sWinRegs[winIdx][0], (data->v2 << 8) | data->v6);
+ SetGpuReg(sWinRegs[winIdx][1], (data->v0 << 8) | data->v4);
+}
+
+static void sub_80C4D30(void)
+{
+ sub_80C4BB8();
+ sub_80C4BE4();
+}
+
+static bool32 sub_80C4D40(u16 a0)
+{
+ if (gUnknown_20399D4 != NULL)
+ return FALSE;
+ if (a0 != MAPSEC_CELADON_CITY)
+ return FALSE;
+ if (gSaveBlock1Ptr->location.mapGroup != MAP_GROUP(CELADON_CITY_DEPARTMENT_STORE_1F))
+ return FALSE;
+ if (gSaveBlock1Ptr->location.mapNum != MAP_NUM(CELADON_CITY_DEPARTMENT_STORE_1F)
+ && gSaveBlock1Ptr->location.mapNum != MAP_NUM(CELADON_CITY_DEPARTMENT_STORE_2F)
+ && gSaveBlock1Ptr->location.mapNum != MAP_NUM(CELADON_CITY_DEPARTMENT_STORE_3F)
+ && gSaveBlock1Ptr->location.mapNum != MAP_NUM(CELADON_CITY_DEPARTMENT_STORE_4F)
+ && gSaveBlock1Ptr->location.mapNum != MAP_NUM(CELADON_CITY_DEPARTMENT_STORE_5F)
+ && gSaveBlock1Ptr->location.mapNum != MAP_NUM(CELADON_CITY_DEPARTMENT_STORE_ROOF)
+ && gSaveBlock1Ptr->location.mapNum != MAP_NUM(CELADON_CITY_DEPARTMENT_STORE_ELEVATOR))
+ return FALSE;
+ return TRUE;
+}
+
+u8 *GetMapName(u8 *dst0, u16 mapsec, u16 fill)
+{
+ u8 *dst;
+ u16 i;
+ u16 idx;;
+ if ((idx = mapsec - MAPSECS_KANTO) <= MAPSEC_SPECIAL_AREA - MAPSECS_KANTO)
+ {
+ if (sub_80C4D40(mapsec) == TRUE)
+ dst = StringCopy(dst0, gMapSecName_CeladonDept);
+ else
+ dst = StringCopy(dst0, sMapNames[idx]);
+ }
+ else
+ {
+ if (fill == 0)
+ fill = 18;
+ return StringFill(dst0, CHAR_SPACE, fill);
+ }
+ if (fill != 0)
+ {
+ for (i = dst - dst0; i < fill; i++)
+ *dst++ = CHAR_SPACE;
+ *dst = EOS;
+ }
+ return dst;
+}
+
+u8 *GetMapNameGeneric(u8 *dest, u16 mapsec)
+{
+ return GetMapName(dest, mapsec, 0);
+}
+
+u8 *sub_80C4E08(u8 *dest, u16 mapsec)
+{
+ return GetMapNameGeneric(dest, mapsec);
+}
+
+static void sub_80C4E18(const u8 *str)
+{
+ if (gUnknown_20399D4->regionMapPermissions[MAPPERM_2] == TRUE)
+ FillWindowPixelBuffer(3, PIXEL_FILL(0));
+ else
+ FillWindowPixelBuffer(3, PIXEL_FILL(15));
+ AddTextPrinterParameterized3(3, 0, 0, 0, gUnknown_83F1CA8, 0, str);
+ CopyWindowToVram(3, 2);
+}
+
+static void sub_80C4E74(const u8 *str)
+{
+ if (gUnknown_20399D4->regionMapPermissions[MAPPERM_2] == TRUE)
+ FillWindowPixelBuffer(4, PIXEL_FILL(0));
+ else
+ FillWindowPixelBuffer(4, PIXEL_FILL(15));
+ AddTextPrinterParameterized3(4, 0, 0, 0, gUnknown_83F1CA8, 0, str);
+ CopyWindowToVram(4, 3);
+}
+
+static void sub_80C4ED0(bool8 mode)
+{
+ if (!mode)
+ {
+ PutWindowTilemap(3);
+ PutWindowTilemap(4);
+ }
+ else
+ {
+ ClearWindowTilemap(3);
+ ClearWindowTilemap(4);
+ }
+}
+
+void MCB2_FlyMap(void)
+{
+ sub_80C51E8();
+ sub_80BFEDC(2);
+}
+
+static void sub_80C4F08(u8 taskId)
+{
+ switch (gUnknown_20399FC->field_0)
+ {
+ case 0:
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
+ sub_80C4398(GetWhichRegionMap(), taskId, sub_80C07E4());
+ sub_80C3008(0, 0);
+ sub_80C41D8(1, 1);
+ sub_80C3154(FALSE);
+ sub_80C4324(FALSE);
+ gUnknown_20399FC->field_0++;
+ break;
+ case 1:
+ if (GetRegionMapPermission(MAPPERM_2) == TRUE)
+ {
+ sub_80C2208(taskId, sub_80C07E4());
+ }
+ else
+ {
+ ShowBg(0);
+ ShowBg(3);
+ ShowBg(1);
+ sub_80C4E18(gText_RegionMap_DPadMove);
+ sub_80C48BC(GetWhichRegionMap(), 25, FALSE);
+ sub_80C4960(GetWhichRegionMap(), 25, FALSE);
+ }
+ gUnknown_20399FC->field_0++;
+ break;
+ case 2:
+ sub_80C4E74(gText_RegionMap_AButtonOK);
+ sub_80C4ED0(FALSE);
+ gUnknown_20399FC->field_0++;
+ break;
+ case 3:
+ if (!gPaletteFade.active)
+ {
+ sub_80C0B18();
+ PutWindowTilemap(0);
+ sub_80C0BB0();
+ PutWindowTilemap(1);
+ gUnknown_20399FC->field_0++;
+ }
+ break;
+ case 4:
+ switch (sub_80C3400())
+ {
+ case 1:
+ case 2:
+ break;
+ case 6:
+ gUnknown_20399FC->field_0 = 6;
+ break;
+ case 3:
+ if (sub_80C3AC8(0) == 2)
+ PlaySE(SE_Z_PAGE);
+ else
+ sub_80C0450();
+ sub_80C3178();
+ sub_80C0B18();
+ sub_80C0BB0();
+ sub_80C0B9C();
+ if (GetMapCursorX() == 21 && GetMapCursorY() == 13)
+ {
+ PlaySE(SE_W255);
+ sub_80C4E74(gText_RegionMap_AButtonCancel);
+ }
+ else if (sub_80C3AC8(0) == 2 || sub_80C3AC8(0) == 4)
+ {
+ sub_80C4E74(gText_RegionMap_AButtonOK);
+ }
+ else
+ {
+ sub_80C4E74(gText_RegionMap_Space);
+ }
+ break;
+ case 4:
+ if ((sub_80C3AC8(0) == 2 || sub_80C3AC8(0) == 4) && GetRegionMapPermission(MAPPERM_3) == TRUE)
+ {
+ switch (get_map_light_level_by_bank_and_number(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum))
+ {
+ case 4:
+ case 8:
+ gUnknown_20399FC->field_2 = FALSE;
+ gUnknown_20399FC->field_0++;
+ break;
+ default:
+ PlaySE(SE_KAIFUKU);
+ gUnknown_20399FC->field_2 = TRUE;
+ gUnknown_20399FC->field_0++;
+ break;
+ }
+ }
+ break;
+ case 5:
+ sub_80C0E70(GetWhichRegionMap(), taskId, sub_80C07F8);
+ break;
+ }
+ break;
+ case 5:
+ if (GetRegionMapPermission(MAPPERM_2) == TRUE)
+ sub_80C2C1C(taskId);
+ gUnknown_20399FC->field_0++;
+ break;
+ case 6:
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK);
+ gUnknown_20399FC->field_0++;
+ break;
+ default:
+ if (!gPaletteFade.active)
+ {
+ if (gUnknown_20399FC->field_2 == TRUE)
+ sub_80C527C(sub_80C3520());
+ sub_80C5208(taskId);
+ }
+ break;
+ }
+}
+
+static void sub_80C51E8(void)
+{
+ gUnknown_20399FC = AllocZeroed(sizeof(struct UnkStruct_20399FC));
+ gUnknown_20399FC->field_0 = 0;
+ gUnknown_20399FC->field_1 = 0;
+}
+
+static void sub_80C5208(u8 taskId)
+{
+ if (GetRegionMapPermission(MAPPERM_2) == TRUE)
+ sub_80C25BC();
+ sub_80C4A04();
+ sub_80C3188();
+ sub_80C4348();
+ sub_80C4D30();
+ sub_80C0898();
+ DestroyTask(taskId);
+ FreeAllWindowBuffers();
+ if (gUnknown_20399FC->field_2 == TRUE)
+ SetMainCallback2(CB2_ReturnToField);
+ else
+ SetMainCallback2(CB2_ReturnToPartyMenuFromFlyMap);
+ FREE_IF_NOT_NULL(gUnknown_20399FC);
+}
+
+static void sub_80C527C(u16 mapsec)
+{
+ u16 idx = mapsec - MAPSECS_KANTO;
+ if (sMapsecToSpawn[idx][2])
+ {
+ sub_805546C(sMapsecToSpawn[idx][2]);
+ sub_8124C1C(sMapsecToSpawn[idx]);
+ }
+ else
+ {
+ warp1_set_2(sMapsecToSpawn[idx][0], sMapsecToSpawn[idx][1], -1);
+ }
+ sub_80842C8();
+}
diff --git a/src/scrcmd.c b/src/scrcmd.c
index fad30a6a8..4eaea9cef 100644
--- a/src/scrcmd.c
+++ b/src/scrcmd.c
@@ -27,14 +27,13 @@
#include "data.h"
#include "field_specials.h"
#include "constants/items.h"
-#include "script_pokemon_util_80A0058.h"
+#include "script_pokemon_util.h"
#include "pokemon_storage_system.h"
#include "party_menu.h"
#include "money.h"
#include "coins.h"
#include "battle_setup.h"
#include "shop.h"
-#include "script_pokemon_80F8.h"
#include "slot_machine.h"
#include "field_effect.h"
#include "fieldmap.h"
diff --git a/src/script_pokemon_util.c b/src/script_pokemon_util.c
new file mode 100644
index 000000000..e12b809c6
--- /dev/null
+++ b/src/script_pokemon_util.c
@@ -0,0 +1,218 @@
+#include "global.h"
+#include "battle.h"
+#include "berry.h"
+#include "daycare.h"
+#include "event_data.h"
+#include "event_object_movement.h"
+#include "load_save.h"
+#include "malloc.h"
+#include "overworld.h"
+#include "party_menu.h"
+#include "pokedex.h"
+#include "script_pokemon_util.h"
+#include "constants/items.h"
+#include "constants/species.h"
+#include "constants/pokemon.h"
+
+static void CB2_ReturnFromChooseHalfParty(void);
+static void CB2_ReturnFromChooseBattleTowerParty(void);
+
+void HealPlayerParty(void)
+{
+ u8 i, j;
+ u8 ppBonuses;
+ u8 arg[4];
+
+ // restore HP.
+ for(i = 0; i < gPlayerPartyCount; i++)
+ {
+ u16 maxHP = GetMonData(&gPlayerParty[i], MON_DATA_MAX_HP);
+ arg[0] = maxHP;
+ arg[1] = maxHP >> 8;
+ SetMonData(&gPlayerParty[i], MON_DATA_HP, arg);
+ ppBonuses = GetMonData(&gPlayerParty[i], MON_DATA_PP_BONUSES);
+
+ // restore PP.
+ for(j = 0; j < MAX_MON_MOVES; j++)
+ {
+ arg[0] = CalculatePPWithBonus(GetMonData(&gPlayerParty[i], MON_DATA_MOVE1 + j), ppBonuses, j);
+ SetMonData(&gPlayerParty[i], MON_DATA_PP1 + j, arg);
+ }
+
+ // since status is u32, the four 0 assignments here are probably for safety to prevent undefined data from reaching SetMonData.
+ arg[0] = 0;
+ arg[1] = 0;
+ arg[2] = 0;
+ arg[3] = 0;
+ SetMonData(&gPlayerParty[i], MON_DATA_STATUS, arg);
+ }
+}
+
+u8 ScriptGiveMon(u16 species, u8 level, u16 item, u32 unused1, u32 unused2, u8 unused3)
+{
+ u16 nationalDexNum;
+ int sentToPc;
+ u8 heldItem[2];
+ struct Pokemon *mon = AllocZeroed(sizeof(struct Pokemon));
+
+ CreateMon(mon, species, level, 32, 0, 0, OT_ID_PLAYER_ID, 0);
+ heldItem[0] = item;
+ heldItem[1] = item >> 8;
+ SetMonData(mon, MON_DATA_HELD_ITEM, heldItem);
+ sentToPc = GiveMonToPlayer(mon);
+ nationalDexNum = SpeciesToNationalPokedexNum(species);
+
+ switch(sentToPc)
+ {
+ case MON_GIVEN_TO_PARTY:
+ case MON_GIVEN_TO_PC:
+ GetSetPokedexFlag(nationalDexNum, FLAG_SET_SEEN);
+ GetSetPokedexFlag(nationalDexNum, FLAG_SET_CAUGHT);
+ break;
+ }
+
+ Free(mon);
+ return sentToPc;
+}
+
+u8 ScriptGiveEgg(u16 species)
+{
+ struct Pokemon *mon = AllocZeroed(sizeof(struct Pokemon));
+ bool8 isEgg;
+ bool8 sentToPc;
+
+ CreateEgg(mon, species, TRUE);
+ isEgg = TRUE;
+ SetMonData(mon, MON_DATA_IS_EGG, &isEgg);
+
+ sentToPc = GiveMonToPlayer(mon);
+ Free(mon);
+ return sentToPc;
+}
+
+void HasEnoughMonsForDoubleBattle(void)
+{
+ switch (GetMonsStateToDoubles())
+ {
+ case PLAYER_HAS_TWO_USABLE_MONS:
+ gSpecialVar_Result = PLAYER_HAS_TWO_USABLE_MONS;
+ break;
+ case PLAYER_HAS_ONE_MON:
+ gSpecialVar_Result = PLAYER_HAS_ONE_MON;
+ break;
+ case PLAYER_HAS_ONE_USABLE_MON:
+ gSpecialVar_Result = PLAYER_HAS_ONE_USABLE_MON;
+ break;
+ }
+}
+
+static bool8 CheckPartyMonHasHeldItem(u16 item)
+{
+ int i;
+
+ for(i = 0; i < PARTY_SIZE; i++)
+ {
+ u16 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2);
+ if (species != SPECIES_NONE && species != SPECIES_EGG && GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM) == item)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 GetNameOfEnigmaBerryInPlayerParty(void)
+{
+ bool8 hasItem = CheckPartyMonHasHeldItem(ITEM_ENIGMA_BERRY);
+ if (hasItem == TRUE)
+ GetBerryNameByBerryType(ItemIdToBerryType(ITEM_ENIGMA_BERRY), gStringVar1);
+
+ return hasItem;
+}
+
+void CreateScriptedWildMon(u16 species, u8 level, u16 item)
+{
+ u8 heldItem[2];
+
+ ZeroEnemyPartyMons();
+ CreateMon(&gEnemyParty[0], species, level, 32, 0, 0, OT_ID_PLAYER_ID, 0);
+ if (item)
+ {
+ heldItem[0] = item;
+ heldItem[1] = item >> 8;
+ SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, heldItem);
+ }
+}
+
+void ScriptSetMonMoveSlot(u8 monIndex, u16 move, u8 slot)
+{
+ if (monIndex > PARTY_SIZE)
+ monIndex = gPlayerPartyCount - 1;
+
+ SetMonMoveSlot(&gPlayerParty[monIndex], move, slot);
+}
+
+// Note: When control returns to the event script, gSpecialVar_Result will be
+// TRUE if the party selection was successful.
+void ChooseHalfPartyForBattle(void)
+{
+ gMain.savedCallback = CB2_ReturnFromChooseHalfParty;
+// VarSet(VAR_FRONTIER_FACILITY, FACILITY_MULTI_OR_EREADER);
+ InitChooseHalfPartyForBattle(0);
+}
+
+static void CB2_ReturnFromChooseHalfParty(void)
+{
+ switch (gSelectedOrderFromParty[0])
+ {
+ case 0:
+ gSpecialVar_Result = FALSE;
+ break;
+ default:
+ gSpecialVar_Result = TRUE;
+ break;
+ }
+
+ SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
+}
+
+void ChooseBattleTowerPlayerParty(void)
+{
+ gMain.savedCallback = CB2_ReturnFromChooseBattleTowerParty;
+ InitChooseHalfPartyForBattle(1);
+}
+
+static void CB2_ReturnFromChooseBattleTowerParty(void)
+{
+ switch (gSelectedOrderFromParty[0])
+ {
+ case 0:
+ LoadPlayerParty();
+ gSpecialVar_Result = FALSE;
+ break;
+ default:
+ ReducePlayerPartyToThree();
+ gSpecialVar_Result = TRUE;
+ break;
+ }
+
+ SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
+}
+
+void ReducePlayerPartyToThree(void)
+{
+ struct Pokemon * party = AllocZeroed(3 * sizeof(struct Pokemon));
+ int i;
+
+ // copy the selected pokemon according to the order.
+ for (i = 0; i < 3; i++)
+ if (gSelectedOrderFromParty[i]) // as long as the order keeps going (did the player select 1 mon? 2? 3?), do not stop
+ party[i] = gPlayerParty[gSelectedOrderFromParty[i] - 1]; // index is 0 based, not literal
+
+ CpuFill32(0, gPlayerParty, sizeof gPlayerParty);
+
+ // overwrite the first 3 with the order copied to.
+ for (i = 0; i < 3; i++)
+ gPlayerParty[i] = party[i];
+
+ CalculatePlayerPartyCount();
+ Free(party);
+}
diff --git a/src/text.c b/src/text.c
index 93a35a07d..a0da0399f 100644
--- a/src/text.c
+++ b/src/text.c
@@ -1180,7 +1180,7 @@ s32 GetStringWidth(u8 fontId, const u8 *str, s16 letterSpacing)
return width;
}
-u8 RenderTextFont9(u8 *pixels, u8 fontId, u8 *str)
+u8 RenderTextFont9(u8 *pixels, u8 fontId, u8 *str, int a3, int a4, int a5, int a6, int a7)
{
u8 shadowColor;
u8 *strLocal;
diff --git a/src/trade.c b/src/trade.c
index 2f48928ec..10ed51d69 100644
--- a/src/trade.c
+++ b/src/trade.c
@@ -2765,10 +2765,10 @@ static bool32 IsDeoxysOrMewUntradable(u16 species, bool8 isObedientBitSet)
int GetUnionRoomTradeMessageId(struct UnkLinkRfuStruct_02022B14Substruct a0, struct UnkLinkRfuStruct_02022B14Substruct a1, u16 species1, u16 species2, u8 type, u16 species3, u8 isObedientBitSet)
{
- u8 r9 = a0.unk_01_0;
- u8 r4 = a0.unk_00_7;
- u8 r10 = a1.unk_01_0;
- u8 r0 = a1.unk_00_7;
+ u8 r9 = a0.hasNationalDex;
+ u8 r4 = a0.isChampion;
+ u8 r10 = a1.hasNationalDex;
+ u8 r0 = a1.isChampion;
u8 r1 = a1.unk_01_2;
u8 r2;
@@ -2845,7 +2845,7 @@ int GetUnionRoomTradeMessageId(struct UnkLinkRfuStruct_02022B14Substruct a0, str
int CanRegisterMonForTradingBoard(struct UnkLinkRfuStruct_02022B14Substruct a0, u16 species, u16 a2, u8 a3)
{
- u8 canTradeEggAndNational = a0.unk_01_0;
+ u8 canTradeEggAndNational = a0.hasNationalDex;
if (IsDeoxysOrMewUntradable(a2, a3))
{
diff --git a/src/vs_seeker.c b/src/vs_seeker.c
index 8478e2114..7d288865c 100644
--- a/src/vs_seeker.c
+++ b/src/vs_seeker.c
@@ -637,7 +637,6 @@ void sub_810C444(void)
}
}
-#ifdef NONMATCHING
bool8 sub_810C4EC(void)
{
if (CheckBagHasItem(ITEM_VS_SEEKER, 1) == TRUE)
@@ -648,18 +647,18 @@ bool8 sub_810C4EC(void)
if (FlagGet(FLAG_SYS_VS_SEEKER_CHARGING) == TRUE)
{
- u16 x;
- do {
- x = (gSaveBlock1Ptr->trainerRematchStepCounter >> 8) & 0xFF;
- } while (0);
+ u8 x = (gSaveBlock1Ptr->trainerRematchStepCounter >> 8) & 0xFF;
+ u32 r4 = 0xFF;
+
if (x < 100)
{
x++;
- gSaveBlock1Ptr->trainerRematchStepCounter = ((u16)(x << 8)) | (gSaveBlock1Ptr->trainerRematchStepCounter & 0xFF);
+ #ifndef NONMATCHING // fool the compiler that r4 has been changed
+ asm("":"=r"(r4));
+ #endif
+ gSaveBlock1Ptr->trainerRematchStepCounter = (gSaveBlock1Ptr->trainerRematchStepCounter & 0xFF) | (x << 8);
}
- do {
- x = (gSaveBlock1Ptr->trainerRematchStepCounter >> 8) & 0xFF;
- } while (0);
+ x = (gSaveBlock1Ptr->trainerRematchStepCounter >> 8) & r4;
if (x == 100)
{
FlagClear(FLAG_SYS_VS_SEEKER_CHARGING);
@@ -671,80 +670,6 @@ bool8 sub_810C4EC(void)
return FALSE;
}
-#else
-NAKED
-bool8 sub_810C4EC(void)
-{
- asm_unified("\tpush {r4-r7,lr}\n"
- "\tmovs r0, 0xB5\n"
- "\tlsls r0, 1\n"
- "\tmovs r1, 0x1\n"
- "\tbl CheckBagHasItem\n"
- "\tlsls r0, 24\n"
- "\tlsrs r0, 24\n"
- "\tcmp r0, 0x1\n"
- "\tbne _0810C516\n"
- "\tldr r0, _0810C568 @ =gSaveBlock1Ptr\n"
- "\tldr r0, [r0]\n"
- "\tmovs r2, 0xC7\n"
- "\tlsls r2, 3\n"
- "\tadds r1, r0, r2\n"
- "\tldrh r2, [r1]\n"
- "\tldrb r0, [r1]\n"
- "\tcmp r0, 0x63\n"
- "\tbhi _0810C516\n"
- "\tadds r0, r2, 0x1\n"
- "\tstrh r0, [r1]\n"
- "_0810C516:\n"
- "\tldr r7, _0810C56C @ =0x00000801\n"
- "\tadds r0, r7, 0\n"
- "\tbl FlagGet\n"
- "\tlsls r0, 24\n"
- "\tlsrs r0, 24\n"
- "\tcmp r0, 0x1\n"
- "\tbne _0810C570\n"
- "\tldr r6, _0810C568 @ =gSaveBlock1Ptr\n"
- "\tldr r0, [r6]\n"
- "\tmovs r5, 0xC7\n"
- "\tlsls r5, 3\n"
- "\tadds r3, r0, r5\n"
- "\tldrh r2, [r3]\n"
- "\tlsrs r1, r2, 8\n"
- "\tmovs r4, 0xFF\n"
- "\tcmp r1, 0x63\n"
- "\tbhi _0810C548\n"
- "\tadds r1, 0x1\n"
- "\tlsls r1, 24\n"
- "\tmovs r0, 0xFF\n"
- "\tands r0, r2\n"
- "\tlsrs r1, 16\n"
- "\torrs r0, r1\n"
- "\tstrh r0, [r3]\n"
- "_0810C548:\n"
- "\tldr r0, [r6]\n"
- "\tadds r0, r5\n"
- "\tldrh r0, [r0]\n"
- "\tlsrs r0, 8\n"
- "\tands r0, r4\n"
- "\tcmp r0, 0x64\n"
- "\tbne _0810C570\n"
- "\tadds r0, r7, 0\n"
- "\tbl FlagClear\n"
- "\tbl sub_810C640\n"
- "\tbl sub_810D0D0\n"
- "\tmovs r0, 0x1\n"
- "\tb _0810C572\n"
- "\t.align 2, 0\n"
- "_0810C568: .4byte gSaveBlock1Ptr\n"
- "_0810C56C: .4byte 0x00000801\n"
- "_0810C570:\n"
- "\tmovs r0, 0\n"
- "_0810C572:\n"
- "\tpop {r4-r7}\n"
- "\tpop {r1}\n"
- "\tbx r1");
-}
-#endif
void sub_810C578(void)
{
@@ -920,13 +845,17 @@ u8 CanUseVsSeeker(void)
}
}
-// Nonmatching due to register roulette
-#ifdef NONMATCHING
static u8 GetVsSeekerResponseInArea(const VsSeekerData * a0)
{
u16 r8 = 0;
u8 sp0 = 0;
s32 vsSeekerIdx;
+ u8 *r2;
+#ifndef NONMATCHING
+ register u32 r3 asm("r3");
+ register s32 r0_ asm("r0");
+ asm("":::"r10", "r8", "r6", "r4");
+#endif
for (vsSeekerIdx = 0; sVsSeeker->trainerInfo[vsSeekerIdx].localId != 0xFF; vsSeekerIdx++)
{
@@ -936,6 +865,7 @@ static u8 GetVsSeekerResponseInArea(const VsSeekerData * a0)
if (!HasTrainerBeenFought(r8))
{
StartTrainerObjectMovementScript(&sVsSeeker->trainerInfo[vsSeekerIdx], gUnknown_8453F60);
+ sVsSeeker->trainerInfo[vsSeekerIdx].trainerIdx += 0;
sVsSeeker->trainerHasNotYetBeenFought = 1;
}
else
@@ -944,7 +874,15 @@ static u8 GetVsSeekerResponseInArea(const VsSeekerData * a0)
if (r7 == 0)
{
StartTrainerObjectMovementScript(&sVsSeeker->trainerInfo[vsSeekerIdx], sMovementScript_TrainerNoRematch);
+ #ifdef NONMATCHING
sVsSeeker->trainerDoesNotWantRematch = 1;
+ #else
+ r2 = (u8 *)sVsSeeker;
+ r3 = 0x431;
+ asm("":::"r1");
+ r2 = &r2[r3];
+ *(r2) |= 2;
+ #endif
}
else
{
@@ -957,7 +895,15 @@ static u8 GetVsSeekerResponseInArea(const VsSeekerData * a0)
if (rval < 30)
{
StartTrainerObjectMovementScript(&sVsSeeker->trainerInfo[vsSeekerIdx], sMovementScript_TrainerNoRematch);
+ #ifdef NONMATCHING
sVsSeeker->trainerDoesNotWantRematch = 1;
+ #else
+ r2 = (u8 *)sVsSeeker;
+ r0_ = 0x431;
+ asm("":::"r1");
+ r2 = &r2[r0_];
+ *(r2) |= 2;
+ #endif
}
else
{
@@ -985,242 +931,6 @@ static u8 GetVsSeekerResponseInArea(const VsSeekerData * a0)
return 1;
return 0;
}
-#else
-NAKED
-static u8 GetVsSeekerResponseInArea(const VsSeekerData * a0)
-{
- asm_unified("\tpush {r4-r7,lr}\n"
- "\tmov r7, r10\n"
- "\tmov r6, r9\n"
- "\tmov r5, r8\n"
- "\tpush {r5-r7}\n"
- "\tsub sp, 0x8\n"
- "\tstr r0, [sp, 0x4]\n"
- "\tmovs r0, 0\n"
- "\tmov r8, r0\n"
- "\tmov r0, sp\n"
- "\tmov r1, r8\n"
- "\tstrb r1, [r0]\n"
- "\tmovs r2, 0\n"
- "\tmov r9, r2\n"
- "\tldr r4, _0810CA14 @ =sVsSeeker\n"
- "\tldr r0, [r4]\n"
- "\tldrb r0, [r0, 0x6]\n"
- "\tcmp r0, 0xFF\n"
- "\tbne _0810C9D0\n"
- "\tb _0810CB2C\n"
- "_0810C9D0:\n"
- "\tadds r6, r4, 0\n"
- "\tmovs r3, 0x86\n"
- "\tlsls r3, 3\n"
- "\tmov r10, r3\n"
- "\tmovs r5, 0\n"
- "_0810C9DA:\n"
- "\tldr r0, [r6]\n"
- "\tadds r0, r5\n"
- "\tbl IsTrainerVisibleOnScreen\n"
- "\tlsls r0, 24\n"
- "\tlsrs r0, 24\n"
- "\tcmp r0, 0x1\n"
- "\tbeq _0810C9EC\n"
- "\tb _0810CB18\n"
- "_0810C9EC:\n"
- "\tldr r0, [r4]\n"
- "\tadds r0, r5\n"
- "\tldrh r0, [r0, 0x4]\n"
- "\tmov r8, r0\n"
- "\tbl HasTrainerBeenFought\n"
- "\tlsls r0, 24\n"
- "\tcmp r0, 0\n"
- "\tbne _0810CA20\n"
- "\tldr r0, [r6]\n"
- "\tadds r0, r5\n"
- "\tldr r1, _0810CA18 @ =gUnknown_8453F60\n"
- "\tbl StartTrainerObjectMovementScript\n"
- "\tldr r2, [r6]\n"
- "\tldr r0, _0810CA1C @ =0x00000431\n"
- "\tadds r2, r0\n"
- "\tldrb r0, [r2]\n"
- "\tmovs r1, 0x1\n"
- "\tb _0810CB14\n"
- "\t.align 2, 0\n"
- "_0810CA14: .4byte sVsSeeker\n"
- "_0810CA18: .4byte gUnknown_8453F60\n"
- "_0810CA1C: .4byte 0x00000431\n"
- "_0810CA20:\n"
- "\tldr r0, [sp, 0x4]\n"
- "\tmov r1, r8\n"
- "\tmov r2, sp\n"
- "\tbl GetNextAvailableRematchTrainer\n"
- "\tlsls r0, 24\n"
- "\tlsrs r7, r0, 24\n"
- "\tcmp r7, 0\n"
- "\tbne _0810CA50\n"
- "\tldr r0, [r6]\n"
- "\tadds r0, r5\n"
- "\tldr r1, _0810CA48 @ =sMovementScript_TrainerNoRematch\n"
- "\tbl StartTrainerObjectMovementScript\n"
- "\tldr r2, [r6]\n"
- "\tldr r3, _0810CA4C @ =0x00000431\n"
- "\tadds r2, r3\n"
- "\tldrb r0, [r2]\n"
- "\tmovs r1, 0x2\n"
- "\tb _0810CB14\n"
- "\t.align 2, 0\n"
- "_0810CA48: .4byte sMovementScript_TrainerNoRematch\n"
- "_0810CA4C: .4byte 0x00000431\n"
- "_0810CA50:\n"
- "\tbl Random\n"
- "\tlsls r0, 16\n"
- "\tlsrs r0, 16\n"
- "\tmovs r1, 0x64\n"
- "\tbl __umodsi3\n"
- "\tlsls r0, 16\n"
- "\tlsrs r4, r0, 16\n"
- "\tmov r0, r9\n"
- "\tmov r1, r8\n"
- "\tbl GetCurVsSeekerResponse\n"
- "\tlsls r0, 24\n"
- "\tlsrs r0, 24\n"
- "\tcmp r0, 0x2\n"
- "\tbne _0810CA76\n"
- "\tmovs r4, 0x64\n"
- "\tb _0810CA7C\n"
- "_0810CA76:\n"
- "\tcmp r0, 0x1\n"
- "\tbne _0810CA7C\n"
- "\tmovs r4, 0\n"
- "_0810CA7C:\n"
- "\tcmp r4, 0x1D\n"
- "\tbhi _0810CAA0\n"
- "\tldr r0, [r6]\n"
- "\tadds r0, r5\n"
- "\tldr r1, _0810CA98 @ =sMovementScript_TrainerNoRematch\n"
- "\tbl StartTrainerObjectMovementScript\n"
- "\tldr r2, [r6]\n"
- "\tldr r0, _0810CA9C @ =0x00000431\n"
- "\tadds r2, r0\n"
- "\tldrb r0, [r2]\n"
- "\tmovs r1, 0x2\n"
- "\tb _0810CB14\n"
- "\t.align 2, 0\n"
- "_0810CA98: .4byte sMovementScript_TrainerNoRematch\n"
- "_0810CA9C: .4byte 0x00000431\n"
- "_0810CAA0:\n"
- "\tldr r0, _0810CB54 @ =gSaveBlock1Ptr\n"
- "\tldr r1, [r0]\n"
- "\tldr r0, [r6]\n"
- "\tadds r0, r5\n"
- "\tldr r2, _0810CB58 @ =0x0000063a\n"
- "\tadds r1, r2\n"
- "\tldrb r0, [r0, 0x6]\n"
- "\tadds r1, r0\n"
- "\tstrb r7, [r1]\n"
- "\tldr r0, [r6]\n"
- "\tadds r0, r5\n"
- "\tldrb r1, [r0, 0x7]\n"
- "\tlsls r0, r1, 3\n"
- "\tadds r0, r1\n"
- "\tlsls r0, 2\n"
- "\tldr r1, _0810CB5C @ =gObjectEvents\n"
- "\tadds r0, r1\n"
- "\tbl npc_coords_shift_still\n"
- "\tldr r0, [r6]\n"
- "\tadds r0, r5\n"
- "\tldr r1, _0810CB60 @ =sMovementScript_TrainerRematch\n"
- "\tbl StartTrainerObjectMovementScript\n"
- "\tldr r2, [r6]\n"
- "\tmov r3, r10\n"
- "\tadds r0, r2, r3\n"
- "\tldrb r1, [r0]\n"
- "\tlsls r1, 1\n"
- "\tmovs r3, 0x80\n"
- "\tlsls r3, 3\n"
- "\tadds r0, r2, r3\n"
- "\tadds r0, r1\n"
- "\tmov r1, r8\n"
- "\tstrh r1, [r0]\n"
- "\tadds r2, r5\n"
- "\tldrb r0, [r2, 0xC]\n"
- "\tbl GetRunningBehaviorFromGraphicsId\n"
- "\tldr r1, [r6]\n"
- "\tmov r3, r10\n"
- "\tadds r2, r1, r3\n"
- "\tmovs r3, 0x84\n"
- "\tlsls r3, 3\n"
- "\tadds r1, r3\n"
- "\tldrb r2, [r2]\n"
- "\tadds r1, r2\n"
- "\tstrb r0, [r1]\n"
- "\tldr r1, [r6]\n"
- "\tadd r1, r10\n"
- "\tldrb r0, [r1]\n"
- "\tadds r0, 0x1\n"
- "\tstrb r0, [r1]\n"
- "\tldr r2, [r6]\n"
- "\tldr r0, _0810CB64 @ =0x00000431\n"
- "\tadds r2, r0\n"
- "\tldrb r0, [r2]\n"
- "\tmovs r1, 0x4\n"
- "_0810CB14:\n"
- "\torrs r0, r1\n"
- "\tstrb r0, [r2]\n"
- "_0810CB18:\n"
- "\tadds r5, 0x10\n"
- "\tmovs r1, 0x1\n"
- "\tadd r9, r1\n"
- "\tldr r4, _0810CB68 @ =sVsSeeker\n"
- "\tldr r0, [r4]\n"
- "\tadds r0, r5\n"
- "\tldrb r0, [r0, 0x6]\n"
- "\tcmp r0, 0xFF\n"
- "\tbeq _0810CB2C\n"
- "\tb _0810C9DA\n"
- "_0810CB2C:\n"
- "\tldr r2, _0810CB68 @ =sVsSeeker\n"
- "\tldr r0, [r2]\n"
- "\tldr r3, _0810CB64 @ =0x00000431\n"
- "\tadds r0, r3\n"
- "\tldrb r1, [r0]\n"
- "\tmovs r0, 0x4\n"
- "\tands r0, r1\n"
- "\tcmp r0, 0\n"
- "\tbeq _0810CB70\n"
- "\tmovs r0, 0x15\n"
- "\tbl PlaySE\n"
- "\tldr r0, _0810CB6C @ =0x00000801\n"
- "\tbl FlagSet\n"
- "\tbl sub_810C640\n"
- "\tmovs r0, 0x2\n"
- "\tb _0810CB7E\n"
- "\t.align 2, 0\n"
- "_0810CB54: .4byte gSaveBlock1Ptr\n"
- "_0810CB58: .4byte 0x0000063a\n"
- "_0810CB5C: .4byte gObjectEvents\n"
- "_0810CB60: .4byte sMovementScript_TrainerRematch\n"
- "_0810CB64: .4byte 0x00000431\n"
- "_0810CB68: .4byte sVsSeeker\n"
- "_0810CB6C: .4byte 0x00000801\n"
- "_0810CB70:\n"
- "\tmovs r0, 0x1\n"
- "\tands r0, r1\n"
- "\tcmp r0, 0\n"
- "\tbne _0810CB7C\n"
- "\tmovs r0, 0\n"
- "\tb _0810CB7E\n"
- "_0810CB7C:\n"
- "\tmovs r0, 0x1\n"
- "_0810CB7E:\n"
- "\tadd sp, 0x8\n"
- "\tpop {r3-r5}\n"
- "\tmov r8, r3\n"
- "\tmov r9, r4\n"
- "\tmov r10, r5\n"
- "\tpop {r4-r7}\n"
- "\tpop {r1}\n"
- "\tbx r1");
-}
-#endif
void sub_810CB90(void)
{