summaryrefslogtreecommitdiff
path: root/src/wonder_transfer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wonder_transfer.c')
-rw-r--r--src/wonder_transfer.c870
1 files changed, 870 insertions, 0 deletions
diff --git a/src/wonder_transfer.c b/src/wonder_transfer.c
new file mode 100644
index 000000000..1928ba12e
--- /dev/null
+++ b/src/wonder_transfer.c
@@ -0,0 +1,870 @@
+#include "global.h"
+#include "bg.h"
+#include "gpu_regs.h"
+#include "palette.h"
+#include "decompress.h"
+#include "malloc.h"
+#include "menu.h"
+#include "pokemon_icon.h"
+#include "union_room.h"
+#include "list_menu.h"
+#include "text_window.h"
+#include "string_util.h"
+#include "link_rfu.h"
+#include "mevent.h"
+#include "mystery_gift.h"
+#include "wonder_transfer.h"
+#include "constants/rgb.h"
+#include "constants/mevent.h"
+
+struct WonderGraphics
+{
+ u8 textPal1:4;
+ u8 textPal2:4;
+ u8 textPal3:4;
+ u8 textPal4:4;
+ const u32 * tiles;
+ const u32 * map;
+ const u16 * pal;
+};
+
+//======================
+// Wonder Cards
+//======================
+
+enum {
+ CARD_WIN_0,
+ CARD_WIN_1,
+ CARD_WIN_2,
+ CARD_WIN_COUNT
+};
+
+#define TAG_ICON_SHADOW 0x8000
+
+struct UnkStruct_203F3C8_02DC
+{
+ u8 unk_00;
+ u8 unk_01[WONDER_CARD_TEXT_LENGTH + 1];
+ u8 unk_42[4];
+};
+
+struct WonderCardData
+{
+ /*0000*/ struct WonderCard card;
+ /*014c*/ struct MEventBuffer_3430_Sub unk_014C;
+ /*0170*/ const struct WonderGraphics * gfx;
+ /*0174*/ u8 enterExitState;
+ /*0175*/ u8 unk_0175;
+ /*0176*/ u16 windowIds[CARD_WIN_COUNT];
+ /*017C*/ u8 monIconSpriteId;
+ /*017D*/ u8 unk_017D[7][2];
+ /*018B*/ u8 unk_018B[WONDER_CARD_TEXT_LENGTH + 1];
+ /*01B4*/ u8 unk_01B4[WONDER_CARD_TEXT_LENGTH + 1];
+ /*01DD*/ u8 unk_01DD[7];
+ /*01E4*/ u8 unk_01E4[4][WONDER_CARD_TEXT_LENGTH + 1];
+ /*0288*/ u8 unk_0288[WONDER_CARD_TEXT_LENGTH + 1];
+ /*02B1*/ u8 unk_02B1[WONDER_CARD_TEXT_LENGTH + 1];
+ /*02DC*/ struct UnkStruct_203F3C8_02DC unk_02DC[8];
+ /*045C*/ u8 buffer_045C[0x1000];
+};
+
+EWRAM_DATA static struct WonderCardData * sWonderCardData = NULL;
+
+static void BufferCardText(void);
+static void DrawCardWindow(u8 whichWindow);
+static void CreateCardSprites(void);
+static void DestroyCardSprites(void);
+
+extern const struct OamData gOamData_AffineOff_ObjNormal_32x16;
+
+static const u8 sCard_TextColorTable[][3] = {
+ {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY},
+ {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY}
+};
+const u8 ALIGNED(4) sCard_TextYOffsets[3] = {7, 4, 7};
+static const struct WindowTemplate sCard_WindowTemplates[] = {
+ [CARD_WIN_0] = {
+ .bg = 1,
+ .tilemapLeft = 1,
+ .tilemapTop = 1,
+ .width = 25,
+ .height = 4,
+ .paletteNum = 2,
+ .baseBlock = 0x029c
+ },
+ [CARD_WIN_1] = {
+ .bg = 1,
+ .tilemapLeft = 1,
+ .tilemapTop = 6,
+ .width = 28,
+ .height = 8,
+ .paletteNum = 2,
+ .baseBlock = 0x01bc
+ },
+ [CARD_WIN_2] = {
+ .bg = 1,
+ .tilemapLeft = 1,
+ .tilemapTop = 14,
+ .width = 28,
+ .height = 5,
+ .paletteNum = 2,
+ .baseBlock = 0x0130
+ }
+};
+
+static const u16 sWonderCardBgPal1[] = INCBIN_U16("graphics/wonder_card/bg1.gbapal");
+static const u16 sWonderCardBgPal2[] = INCBIN_U16("graphics/wonder_card/bg2.gbapal");
+static const u16 sWonderCardBgPal3[] = INCBIN_U16("graphics/wonder_card/bg3.gbapal");
+static const u16 sWonderCardBgPal4[] = INCBIN_U16("graphics/wonder_card/bg4.gbapal");
+static const u16 sWonderCardBgPal5[] = INCBIN_U16("graphics/wonder_card/bg5.gbapal");
+static const u16 sWonderCardBgPal6[] = INCBIN_U16("graphics/wonder_card/bg6.gbapal");
+static const u16 sWonderCardBgPal7[] = INCBIN_U16("graphics/wonder_card/bg7.gbapal");
+static const u16 sWonderCardBgPal8[] = INCBIN_U16("graphics/wonder_card/bg8.gbapal");
+static const u32 sWonderCardBgGfx1[] = INCBIN_U32("graphics/wonder_card/bg1.4bpp.lz");
+static const u32 sWonderCardBgTilemap1[] = INCBIN_U32("graphics/wonder_card/bg1.bin.lz");
+static const u32 sWonderCardBgGfx2[] = INCBIN_U32("graphics/wonder_card/bg2.4bpp.lz");
+static const u32 sWonderCardBgTilemap2[] = INCBIN_U32("graphics/wonder_card/bg2.bin.lz");
+static const u32 sWonderCardBgGfx3[] = INCBIN_U32("graphics/wonder_card/bg3.4bpp.lz");
+static const u32 sWonderCardBgTilemap3[] = INCBIN_U32("graphics/wonder_card/bg3.bin.lz");
+static const u32 sWonderCardBgGfx7[] = INCBIN_U32("graphics/wonder_card/bg7.4bpp.lz");
+static const u32 sWonderCardBgTilemap7[] = INCBIN_U32("graphics/wonder_card/bg7.bin.lz");
+static const u32 sWonderCardBgGfx8[] = INCBIN_U32("graphics/wonder_card/bg8.4bpp.lz");
+static const u32 sWonderCardBgTilemap8[] = INCBIN_U32("graphics/wonder_card/bg8.bin.lz");
+static const u16 sIconShadowPal1[] = INCBIN_U16("graphics/wonder_card/icon_shadow_1.gbapal");
+static const u16 sIconShadowPal2[] = INCBIN_U16("graphics/wonder_card/icon_shadow_2.gbapal");
+static const u16 sIconShadowPal3[] = INCBIN_U16("graphics/wonder_card/icon_shadow_3.gbapal");
+static const u16 sIconShadowPal4[] = INCBIN_U16("graphics/wonder_card/icon_shadow_4.gbapal");
+static const u16 sIconShadowPal5[] = INCBIN_U16("graphics/wonder_card/icon_shadow_5.gbapal");
+static const u16 sIconShadowPal6[] = INCBIN_U16("graphics/wonder_card/icon_shadow_6.gbapal");
+static const u16 sIconShadowPal7[] = INCBIN_U16("graphics/wonder_card/icon_shadow_7.gbapal");
+static const u16 sIconShadowPal8[] = INCBIN_U16("graphics/wonder_card/icon_shadow_8.gbapal");
+static const u32 sIconShadowGfx[] = INCBIN_U32("graphics/wonder_card/icon_shadow.4bpp.lz");
+
+static const struct CompressedSpriteSheet sSpriteSheet_IconShadow = {
+ sIconShadowGfx, 0x100, TAG_ICON_SHADOW
+};
+
+static const struct SpritePalette sSpritePalettes_IconShadow[] = {
+ {sIconShadowPal1, TAG_ICON_SHADOW},
+ {sIconShadowPal2, TAG_ICON_SHADOW},
+ {sIconShadowPal3, TAG_ICON_SHADOW},
+ {sIconShadowPal4, TAG_ICON_SHADOW},
+ {sIconShadowPal5, TAG_ICON_SHADOW},
+ {sIconShadowPal6, TAG_ICON_SHADOW},
+ {sIconShadowPal7, TAG_ICON_SHADOW},
+ {sIconShadowPal8, TAG_ICON_SHADOW}
+};
+
+static const struct SpriteTemplate sSpriteTemplate_IconShadow = {
+ .tileTag = TAG_ICON_SHADOW,
+ .paletteTag = TAG_ICON_SHADOW,
+ .oam = &gOamData_AffineOff_ObjNormal_32x16,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy
+};
+
+static const struct WonderGraphics sCardGraphics[NUM_WONDER_BGS] = {
+ {.textPal1 = 1, .textPal2 = 0, .textPal3 = 0, .textPal4 = 0, .tiles = sWonderCardBgGfx1, .map = sWonderCardBgTilemap1, .pal = sWonderCardBgPal1},
+ {.textPal1 = 1, .textPal2 = 0, .textPal3 = 0, .textPal4 = 1, .tiles = sWonderCardBgGfx2, .map = sWonderCardBgTilemap2, .pal = sWonderCardBgPal2},
+ {.textPal1 = 1, .textPal2 = 0, .textPal3 = 0, .textPal4 = 2, .tiles = sWonderCardBgGfx3, .map = sWonderCardBgTilemap3, .pal = sWonderCardBgPal3},
+ {.textPal1 = 1, .textPal2 = 0, .textPal3 = 0, .textPal4 = 3, .tiles = sWonderCardBgGfx3, .map = sWonderCardBgTilemap3, .pal = sWonderCardBgPal4},
+ {.textPal1 = 1, .textPal2 = 0, .textPal3 = 0, .textPal4 = 4, .tiles = sWonderCardBgGfx3, .map = sWonderCardBgTilemap3, .pal = sWonderCardBgPal5},
+ {.textPal1 = 1, .textPal2 = 0, .textPal3 = 0, .textPal4 = 5, .tiles = sWonderCardBgGfx3, .map = sWonderCardBgTilemap3, .pal = sWonderCardBgPal6},
+ {.textPal1 = 1, .textPal2 = 0, .textPal3 = 0, .textPal4 = 6, .tiles = sWonderCardBgGfx7, .map = sWonderCardBgTilemap7, .pal = sWonderCardBgPal7},
+ {.textPal1 = 1, .textPal2 = 0, .textPal3 = 0, .textPal4 = 7, .tiles = sWonderCardBgGfx8, .map = sWonderCardBgTilemap8, .pal = sWonderCardBgPal8}
+};
+
+bool32 WonderCard_Init(struct WonderCard * card, struct MEventBuffer_3430_Sub * r6)
+{
+ if (card == NULL || r6 == NULL)
+ return FALSE;
+ sWonderCardData = AllocZeroed(sizeof(*sWonderCardData));
+ if (sWonderCardData == NULL)
+ return FALSE;
+ sWonderCardData->card = *card;
+ sWonderCardData->unk_014C = *r6;
+ if (sWonderCardData->card.bgType >= ARRAY_COUNT(sCardGraphics))
+ sWonderCardData->card.bgType = 0;
+ if (sWonderCardData->card.unk_08_0 >= ARRAY_COUNT(sCard_TextYOffsets))
+ sWonderCardData->card.unk_08_0 = 0;
+ if (sWonderCardData->card.unk_09 > ARRAY_COUNT(sWonderCardData->unk_017D))
+ sWonderCardData->card.unk_09 = 0;
+ sWonderCardData->gfx = &sCardGraphics[sWonderCardData->card.bgType];
+ return TRUE;
+}
+
+void WonderCard_Destroy(void)
+{
+ if (sWonderCardData != NULL)
+ {
+ *sWonderCardData = (struct WonderCardData){};
+ Free(sWonderCardData);
+ sWonderCardData = NULL;
+ }
+}
+
+s32 WonderCard_Enter(void)
+{
+ if (sWonderCardData == NULL)
+ return -1;
+ switch(sWonderCardData->enterExitState)
+ {
+ case 0:
+ BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
+ break;
+ case 1:
+ if (UpdatePaletteFade())
+ return 0;
+ break;
+ case 2:
+ FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 0, 30, 20);
+ FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 30, 20);
+ FillBgTilemapBufferRect_Palette0(2, 0x000, 0, 0, 30, 20);
+ CopyBgTilemapBufferToVram(0);
+ CopyBgTilemapBufferToVram(1);
+ CopyBgTilemapBufferToVram(2);
+ DecompressAndCopyTileDataToVram(2, sWonderCardData->gfx->tiles, 0, 0x008, 0);
+ sWonderCardData->windowIds[CARD_WIN_0] = AddWindow(&sCard_WindowTemplates[CARD_WIN_0]);
+ sWonderCardData->windowIds[CARD_WIN_1] = AddWindow(&sCard_WindowTemplates[CARD_WIN_1]);
+ sWonderCardData->windowIds[CARD_WIN_2] = AddWindow(&sCard_WindowTemplates[CARD_WIN_2]);
+ break;
+ case 3:
+ if (FreeTempTileDataBuffersIfPossible())
+ return 0;
+ LoadPalette(GetTextWindowPalette(1), 0x20, 0x20);
+ gPaletteFade.bufferTransferDisabled = TRUE;
+ LoadPalette(sWonderCardData->gfx->pal, 0x10, 0x20);
+ LZ77UnCompWram(sWonderCardData->gfx->map, sWonderCardData->buffer_045C);
+ CopyRectToBgTilemapBufferRect(2, sWonderCardData->buffer_045C, 0, 0, 30, 20, 0, 0, 30, 20, 1, 0x008, 0);
+ CopyBgTilemapBufferToVram(2);
+ break;
+ case 4:
+ BufferCardText();
+ break;
+ case 5:
+ DrawCardWindow(CARD_WIN_0);
+ DrawCardWindow(CARD_WIN_1);
+ DrawCardWindow(CARD_WIN_2);
+ CopyBgTilemapBufferToVram(1);
+ break;
+ case 6:
+ LoadMonIconPalettes();
+ break;
+ case 7:
+ ShowBg(1);
+ ShowBg(2);
+ gPaletteFade.bufferTransferDisabled = FALSE;
+ CreateCardSprites();
+ BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
+ UpdatePaletteFade();
+ break;
+ default:
+ if (UpdatePaletteFade())
+ return 0;
+ sWonderCardData->enterExitState = 0;
+ return 1;
+ }
+ ++sWonderCardData->enterExitState;
+ return 0;
+}
+
+s32 WonderCard_Exit(bool32 flag)
+{
+ if (sWonderCardData == NULL)
+ return -1;
+ switch (sWonderCardData->enterExitState)
+ {
+ case 0:
+ BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
+ break;
+ case 1:
+ if (UpdatePaletteFade())
+ return 0;
+ break;
+ case 2:
+ FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 0, 30, 20);
+ FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 30, 20);
+ FillBgTilemapBufferRect_Palette0(2, 0x000, 0, 0, 30, 20);
+ CopyBgTilemapBufferToVram(0);
+ CopyBgTilemapBufferToVram(1);
+ CopyBgTilemapBufferToVram(2);
+ break;
+ case 3:
+ HideBg(1);
+ HideBg(2);
+ RemoveWindow(sWonderCardData->windowIds[CARD_WIN_2]);
+ RemoveWindow(sWonderCardData->windowIds[CARD_WIN_1]);
+ RemoveWindow(sWonderCardData->windowIds[CARD_WIN_0]);
+ break;
+ case 4:
+ DestroyCardSprites();
+ FreeMonIconPalettes();
+ break;
+ case 5:
+ PrintMysteryGiftOrEReaderTopMenu(gGiftIsFromEReader, flag);
+ CopyBgTilemapBufferToVram(0);
+ BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
+ break;
+ default:
+ if (UpdatePaletteFade())
+ return 0;
+ sWonderCardData->enterExitState = 0;
+ return 1;
+ }
+ ++sWonderCardData->enterExitState;
+ return 0;
+}
+
+static void BufferCardText(void)
+{
+ u16 i = 0;
+ u16 r6;
+ u16 sp0[3] = {0, 0, 0};
+
+ memcpy(sWonderCardData->unk_018B, sWonderCardData->card.unk_0A, WONDER_CARD_TEXT_LENGTH);
+ sWonderCardData->unk_018B[WONDER_CARD_TEXT_LENGTH] = EOS;
+ memcpy(sWonderCardData->unk_01B4, sWonderCardData->card.unk_32, WONDER_CARD_TEXT_LENGTH);
+ sWonderCardData->unk_01B4[WONDER_CARD_TEXT_LENGTH] = EOS;
+ if (sWonderCardData->card.unk_04 > 999999)
+ sWonderCardData->card.unk_04 = 999999;
+ ConvertIntToDecimalStringN(sWonderCardData->unk_01DD, sWonderCardData->card.unk_04, STR_CONV_MODE_LEFT_ALIGN, 6);
+ for (i = 0; i < 4; i++)
+ {
+ memcpy(sWonderCardData->unk_01E4[i], sWonderCardData->card.unk_5A[i], WONDER_CARD_TEXT_LENGTH);
+ sWonderCardData->unk_01E4[i][WONDER_CARD_TEXT_LENGTH] = EOS;
+ }
+ memcpy(sWonderCardData->unk_0288, sWonderCardData->card.unk_FA, WONDER_CARD_TEXT_LENGTH);
+ sWonderCardData->unk_0288[WONDER_CARD_TEXT_LENGTH] = EOS;
+ switch (sWonderCardData->card.unk_08_0)
+ {
+ case 0:
+ memcpy(sWonderCardData->unk_02B1, sWonderCardData->card.unk_122, WONDER_CARD_TEXT_LENGTH);
+ sWonderCardData->unk_02B1[WONDER_CARD_TEXT_LENGTH] = EOS;
+ break;
+ case 1:
+ sWonderCardData->unk_02B1[0] = EOS;
+ break;
+ case 2:
+ sWonderCardData->unk_02B1[0] = EOS;
+ sp0[0] = sWonderCardData->unk_014C.unk_00 < 999 ? sWonderCardData->unk_014C.unk_00 : 999;
+ sp0[1] = sWonderCardData->unk_014C.unk_02 < 999 ? sWonderCardData->unk_014C.unk_02 : 999;
+ sp0[2] = sWonderCardData->unk_014C.unk_04 < 999 ? sWonderCardData->unk_014C.unk_04 : 999;
+ for (i = 0; i < 8; i++)
+ {
+ memset(sWonderCardData->unk_02DC[i].unk_42, EOS, sizeof(sWonderCardData->unk_02DC[i].unk_42));
+ memset(sWonderCardData->unk_02DC[i].unk_01, EOS, sizeof(sWonderCardData->unk_02DC[i].unk_01));
+ }
+ for (i = 0, r6 = 0; i < WONDER_CARD_TEXT_LENGTH; i++)
+ {
+ if (sWonderCardData->card.unk_122[i] != CHAR_DYNAMIC)
+ {
+ sWonderCardData->unk_02DC[sWonderCardData->unk_0175].unk_01[r6] = sWonderCardData->card.unk_122[i];
+ r6++;
+ }
+ else
+ {
+ u8 r3 = sWonderCardData->card.unk_122[i + 1];
+ if (r3 > 2)
+ {
+ i += 2;
+ }
+ else
+ {
+ ConvertIntToDecimalStringN(sWonderCardData->unk_02DC[sWonderCardData->unk_0175].unk_42, sp0[r3], STR_CONV_MODE_LEADING_ZEROS, 3);
+ sWonderCardData->unk_02DC[sWonderCardData->unk_0175].unk_00 = sWonderCardData->card.unk_122[i + 2];
+ sWonderCardData->unk_0175++;
+ if (sWonderCardData->unk_0175 > 7)
+ break;
+ r6 = 0;
+ i += 2;
+ }
+ }
+ }
+ }
+}
+
+static void DrawCardWindow(u8 whichWindow)
+{
+ s8 sp0C = 0;
+ s32 windowId = sWonderCardData->windowIds[whichWindow];
+ PutWindowTilemap(windowId);
+ FillWindowPixelBuffer(windowId, 0);
+ switch (whichWindow)
+ {
+ case CARD_WIN_0:
+ {
+ s32 x;
+ AddTextPrinterParameterized3(windowId, 3, 0, 1, sCard_TextColorTable[sWonderCardData->gfx->textPal1], 0, sWonderCardData->unk_018B);
+ x = 160 - GetStringWidth(3, sWonderCardData->unk_01B4, GetFontAttribute(3, FONTATTR_LETTER_SPACING));
+ if (x < 0)
+ x = 0;
+ AddTextPrinterParameterized3(windowId, 3, x, 17, sCard_TextColorTable[sWonderCardData->gfx->textPal1], 0, sWonderCardData->unk_01B4);
+ if (sWonderCardData->card.unk_04 != 0)
+ AddTextPrinterParameterized3(windowId, 1, 166, 17, sCard_TextColorTable[sWonderCardData->gfx->textPal1], 0, sWonderCardData->unk_01DD);
+ break;
+ }
+ case CARD_WIN_1:
+ for (; sp0C < 4; sp0C++)
+ AddTextPrinterParameterized3(windowId, 3, 0, 16 * sp0C + 2, sCard_TextColorTable[sWonderCardData->gfx->textPal2], 0, sWonderCardData->unk_01E4[sp0C]);
+ break;
+ case CARD_WIN_2:
+ AddTextPrinterParameterized3(windowId, 3, 0, sCard_TextYOffsets[sWonderCardData->card.unk_08_0], sCard_TextColorTable[sWonderCardData->gfx->textPal3], 0, sWonderCardData->unk_0288);
+ if (sWonderCardData->card.unk_08_0 != 2)
+ {
+ AddTextPrinterParameterized3(windowId, 3, 0, 16 + sCard_TextYOffsets[sWonderCardData->card.unk_08_0], sCard_TextColorTable[sWonderCardData->gfx->textPal3], 0, sWonderCardData->unk_02B1);
+ }
+ else
+ {
+ s32 x = 0;
+ s32 y = sCard_TextYOffsets[sWonderCardData->card.unk_08_0] + 16;
+ s32 spacing = GetFontAttribute(3, FONTATTR_LETTER_SPACING);
+ for (; sp0C < sWonderCardData->unk_0175; sp0C++)
+ {
+ AddTextPrinterParameterized3(windowId, 3, x, y, sCard_TextColorTable[sWonderCardData->gfx->textPal3], 0, sWonderCardData->unk_02DC[sp0C].unk_01);
+ if (sWonderCardData->unk_02DC[sp0C].unk_42[0] != EOS)
+ {
+ x += GetStringWidth(3, sWonderCardData->unk_02DC[sp0C].unk_01, spacing);
+ AddTextPrinterParameterized3(windowId, 3, x, y, sCard_TextColorTable[sWonderCardData->gfx->textPal3], 0, sWonderCardData->unk_02DC[sp0C].unk_42);
+ x += GetStringWidth(3, sWonderCardData->unk_02DC[sp0C].unk_42, spacing) + sWonderCardData->unk_02DC[sp0C].unk_00;
+ }
+ }
+ }
+ break;
+ }
+ CopyWindowToVram(windowId, 3);
+}
+
+static void CreateCardSprites(void)
+{
+ u8 r7 = 0;
+ sWonderCardData->monIconSpriteId = SPRITE_NONE;
+ if (sWonderCardData->unk_014C.unk_06 != SPECIES_NONE)
+ {
+ sWonderCardData->monIconSpriteId = CreateMonIconNoPersonality(GetIconSpeciesNoPersonality(sWonderCardData->unk_014C.unk_06), SpriteCallbackDummy, 220, 20, 0, FALSE);
+ gSprites[sWonderCardData->monIconSpriteId].oam.priority = 2;
+ }
+ if (sWonderCardData->card.unk_09 != 0 && sWonderCardData->card.unk_08_0 == 1)
+ {
+ LoadCompressedSpriteSheetUsingHeap(&sSpriteSheet_IconShadow);
+ LoadSpritePalette(&sSpritePalettes_IconShadow[sWonderCardData->gfx->textPal4]);
+ for (; r7 < sWonderCardData->card.unk_09; r7++)
+ {
+ sWonderCardData->unk_017D[r7][0] = SPRITE_NONE;
+ sWonderCardData->unk_017D[r7][1] = SPRITE_NONE;
+ sWonderCardData->unk_017D[r7][0] = CreateSprite(&sSpriteTemplate_IconShadow, 216 - 32 * r7, 144, 8);
+ if (sWonderCardData->unk_014C.unk_08[0][r7] != SPECIES_NONE)
+ sWonderCardData->unk_017D[r7][1] = CreateMonIconNoPersonality(GetIconSpeciesNoPersonality(sWonderCardData->unk_014C.unk_08[0][r7]),
+ SpriteCallbackDummy,
+ 216 - 32 * r7,
+ 136, 0, 0);
+ }
+ }
+}
+
+static void DestroyCardSprites(void)
+{
+ u8 r6 = 0;
+ if (sWonderCardData->monIconSpriteId != SPRITE_NONE)
+ FreeAndDestroyMonIconSprite(&gSprites[sWonderCardData->monIconSpriteId]);
+ if (sWonderCardData->card.unk_09 != 0 && sWonderCardData->card.unk_08_0 == 1)
+ {
+ for (; r6 < sWonderCardData->card.unk_09; r6++)
+ {
+ if (sWonderCardData->unk_017D[r6][0] != SPRITE_NONE)
+ DestroySprite(&gSprites[sWonderCardData->unk_017D[r6][0]]);
+ if (sWonderCardData->unk_017D[r6][1] != SPRITE_NONE)
+ FreeAndDestroyMonIconSprite(&gSprites[sWonderCardData->unk_017D[r6][1]]);
+ }
+ FreeSpriteTilesByTag(TAG_ICON_SHADOW);
+ FreeSpritePaletteByTag(TAG_ICON_SHADOW);
+ }
+}
+
+//======================
+// Wonder News
+//======================
+
+enum {
+ NEWS_WIN_0,
+ NEWS_WIN_1,
+ NEWS_WIN_COUNT
+};
+
+#define TAG_ARROWS 0x1000
+
+struct WonderNewsData
+{
+ /*0000*/ struct WonderNews news;
+ /*01bc*/ const struct WonderGraphics * gfx;
+ /*01c0*/ u8 arrowsRemoved:1;
+ u8 enterExitState:7;
+ /*01c1*/ u8 arrowTaskId;
+ /*01c2*/ bool8 scrolling:1;
+ u8 scrollIncrement:7;
+ /*01c3*/ bool8 scrollingDown:1;
+ u8 scrollTotal:7;
+ /*01c4*/ u16 scrollEnd;
+ /*01c6*/ u16 scrollOffset;
+ /*01c8*/ u16 windowIds[NEWS_WIN_COUNT];
+ /*01cc*/ u8 filler_01CC[2];
+ /*01ce*/ u8 unk_01CE[WONDER_NEWS_TEXT_LENGTH + 1];
+ /*01f7*/ u8 unk_01F7[10][WONDER_NEWS_TEXT_LENGTH + 1];
+ /*0394*/ struct ScrollArrowsTemplate arrowsTemplate;
+ /*03a4*/ u8 buffer_03A4[0x1000];
+};
+
+EWRAM_DATA static struct WonderNewsData * sWonderNewsData = NULL;
+
+static void BufferNewsText(void);
+static void DrawNewsWindows(void);
+static void UpdateNewsScroll(void);
+
+static const u8 sNews_TextColorTable[][3] = {
+ {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY},
+ {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY}
+};
+
+static const struct WindowTemplate sNews_WindowTemplates[] = {
+ [NEWS_WIN_0] = {
+ .bg = 0,
+ .tilemapLeft = 1,
+ .tilemapTop = 0,
+ .width = 28,
+ .height = 3,
+ .paletteNum = 2,
+ .baseBlock = 0x2AC
+ },
+ [NEWS_WIN_1] = {
+ .bg = 2,
+ .tilemapLeft = 1,
+ .tilemapTop = 3,
+ .width = 28,
+ .height = 20,
+ .paletteNum = 2,
+ .baseBlock = 0x07C
+ }
+};
+
+static const struct ScrollArrowsTemplate sNews_ArrowsTemplate = {
+ .firstArrowType = SCROLL_ARROW_UP,
+ .firstX = 232,
+ .firstY = 24,
+ .secondArrowType = SCROLL_ARROW_DOWN,
+ .secondX = 232,
+ .secondY = 152,
+ .fullyUpThreshold = 0,
+ .fullyDownThreshold = 2,
+ .tileTag = TAG_ARROWS,
+ .palTag = TAG_ARROWS,
+ .palNum = 0
+};
+
+static const u16 sWonderNewsPal1[] = INCBIN_U16("graphics/wonder_news/bg1.gbapal");
+static const u16 sWonderNewsPal7[] = INCBIN_U16("graphics/wonder_news/bg7.gbapal");
+static const u16 sWonderNewsPal8[] = INCBIN_U16("graphics/wonder_news/bg8.gbapal");
+static const u32 sWonderNewsGfx1[] = INCBIN_U32("graphics/wonder_news/bg1.4bpp.lz");
+static const u32 sWonderNewsTilemap1[] = INCBIN_U32("graphics/wonder_news/bg1.bin.lz");
+static const u32 sWonderNewsGfx2[] = INCBIN_U32("graphics/wonder_news/bg2.4bpp.lz");
+static const u32 sWonderNewsTilemap2[] = INCBIN_U32("graphics/wonder_news/bg2.bin.lz");
+static const u32 sWonderNewsGfx3[] = INCBIN_U32("graphics/wonder_news/bg3.4bpp.lz");
+static const u32 sWonderNewsTilemap3[] = INCBIN_U32("graphics/wonder_news/bg3.bin.lz");
+static const u32 sWonderNewsGfx7[] = INCBIN_U32("graphics/wonder_news/bg7.4bpp.lz");
+static const u32 sWonderNewsTilemap7[] = INCBIN_U32("graphics/wonder_news/bg7.bin.lz");
+static const u32 sWonderNewsGfx8[] = INCBIN_U32("graphics/wonder_news/bg8.4bpp.lz");
+static const u32 sWonderNewsTilemap8[] = INCBIN_U32("graphics/wonder_news/bg8.bin.lz");
+
+static const struct WonderGraphics sNewsGraphics[NUM_WONDER_BGS] = {
+ {1, 0, 0, 0, sWonderNewsGfx1, sWonderNewsTilemap1, sWonderNewsPal1},
+ {1, 0, 0, 0, sWonderNewsGfx2, sWonderNewsTilemap2, sWonderCardBgPal2},
+ {1, 0, 0, 0, sWonderNewsGfx3, sWonderNewsTilemap3, sWonderCardBgPal3},
+ {1, 0, 0, 0, sWonderNewsGfx3, sWonderNewsTilemap3, sWonderCardBgPal4},
+ {1, 0, 0, 0, sWonderNewsGfx3, sWonderNewsTilemap3, sWonderCardBgPal5},
+ {1, 0, 0, 0, sWonderNewsGfx3, sWonderNewsTilemap3, sWonderCardBgPal6},
+ {1, 0, 0, 0, sWonderNewsGfx7, sWonderNewsTilemap7, sWonderNewsPal7},
+ {1, 0, 0, 0, sWonderNewsGfx8, sWonderNewsTilemap8, sWonderNewsPal8}
+};
+
+bool32 WonderNews_Init(const struct WonderNews * news)
+{
+ if (news == NULL)
+ return FALSE;
+ sWonderNewsData = AllocZeroed(sizeof(*sWonderNewsData));
+ if (sWonderNewsData == NULL)
+ return FALSE;
+ sWonderNewsData->news = *news;
+ if (sWonderNewsData->news.bgType >= ARRAY_COUNT(sNewsGraphics))
+ sWonderNewsData->news.bgType = 0;
+ sWonderNewsData->gfx = &sNewsGraphics[sWonderNewsData->news.bgType];
+ sWonderNewsData->arrowTaskId = TASK_NONE;
+ return TRUE;
+}
+
+void WonderNews_Destroy(void)
+{
+ if (sWonderNewsData != NULL)
+ {
+ *sWonderNewsData = (struct WonderNewsData){};
+ Free(sWonderNewsData);
+ sWonderNewsData = NULL;
+ }
+}
+
+s32 WonderNews_Enter(void)
+{
+ if (sWonderNewsData == NULL)
+ return -1;
+
+ switch (sWonderNewsData->enterExitState)
+ {
+ case 0:
+ BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
+ break;
+ case 1:
+ if (UpdatePaletteFade())
+ return 0;
+ ChangeBgY(0, 0, 0);
+ ChangeBgY(1, 0, 0);
+ ChangeBgY(2, 0, 0);
+ ChangeBgY(3, 0, 0);
+ SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(0, DISPLAY_WIDTH));
+ SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(26, 152));
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ);
+ SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG1 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ);
+ SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON);
+ break;
+ case 2:
+ FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 0, 30, 20);
+ FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 30, 20);
+ FillBgTilemapBufferRect_Palette0(2, 0x000, 0, 0, 30, 20);
+ FillBgTilemapBufferRect_Palette0(3, 0x000, 0, 0, 30, 20);
+ CopyBgTilemapBufferToVram(0);
+ CopyBgTilemapBufferToVram(1);
+ CopyBgTilemapBufferToVram(2);
+ CopyBgTilemapBufferToVram(3);
+ DecompressAndCopyTileDataToVram(3, sWonderNewsData->gfx->tiles, 0, 8, 0);
+ sWonderNewsData->windowIds[NEWS_WIN_0] = AddWindow(&sNews_WindowTemplates[NEWS_WIN_0]);
+ sWonderNewsData->windowIds[NEWS_WIN_1] = AddWindow(&sNews_WindowTemplates[NEWS_WIN_1]);
+ break;
+ case 3:
+ if (FreeTempTileDataBuffersIfPossible())
+ return 0;
+ LoadPalette(GetTextWindowPalette(1), 0x20, 0x20);
+ gPaletteFade.bufferTransferDisabled = TRUE;
+ LoadPalette(sWonderNewsData->gfx->pal, 0x10, 0x20);
+ LZ77UnCompWram(sWonderNewsData->gfx->map, sWonderNewsData->buffer_03A4);
+ CopyRectToBgTilemapBufferRect(1, sWonderNewsData->buffer_03A4, 0, 0, 30, 3, 0, 0, 30, 3, 1, 8, 0);
+ CopyRectToBgTilemapBufferRect(3, sWonderNewsData->buffer_03A4, 0, 3, 30, 23, 0, 3, 30, 23, 1, 8, 0);
+ CopyBgTilemapBufferToVram(1);
+ CopyBgTilemapBufferToVram(3);
+ break;
+ case 4:
+ BufferNewsText();
+ break;
+ case 5:
+ DrawNewsWindows();
+ CopyBgTilemapBufferToVram(0);
+ CopyBgTilemapBufferToVram(2);
+ break;
+ case 6:
+ ShowBg(1);
+ ShowBg(2);
+ ShowBg(3);
+ gPaletteFade.bufferTransferDisabled = FALSE;
+ sWonderNewsData->arrowTaskId = AddScrollIndicatorArrowPair(&sWonderNewsData->arrowsTemplate, &sWonderNewsData->scrollOffset);
+ BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
+ UpdatePaletteFade();
+ break;
+ default:
+ if (UpdatePaletteFade())
+ return 0;
+ sWonderNewsData->enterExitState = 0;
+ return 1;
+ }
+
+ ++sWonderNewsData->enterExitState;
+ return 0;
+}
+
+s32 WonderNews_Exit(bool32 flag)
+{
+ if (sWonderNewsData == NULL)
+ return -1;
+ switch (sWonderNewsData->enterExitState)
+ {
+ case 0:
+ BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
+ break;
+ case 1:
+ if (UpdatePaletteFade())
+ return 0;
+ ChangeBgY(2, 0, 0);
+ SetGpuReg(REG_OFFSET_WIN0H, 0);
+ SetGpuReg(REG_OFFSET_WIN0V, 0);
+ SetGpuReg(REG_OFFSET_WININ, 0);
+ SetGpuReg(REG_OFFSET_WINOUT, 0);
+ ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON);
+ break;
+ case 2:
+ FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 0, 30, 20);
+ FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 30, 20);
+ FillBgTilemapBufferRect_Palette0(2, 0x000, 0, 0, 30, 24);
+ FillBgTilemapBufferRect_Palette0(3, 0x000, 0, 0, 30, 24);
+ CopyBgTilemapBufferToVram(0);
+ CopyBgTilemapBufferToVram(1);
+ CopyBgTilemapBufferToVram(2);
+ CopyBgTilemapBufferToVram(3);
+ break;
+ case 3:
+ HideBg(1);
+ HideBg(2);
+ RemoveWindow(sWonderNewsData->windowIds[NEWS_WIN_1]);
+ RemoveWindow(sWonderNewsData->windowIds[NEWS_WIN_0]);
+ break;
+ case 4:
+ ChangeBgY(2, 0, 0);
+ ChangeBgY(3, 0, 0);
+ if (sWonderNewsData->arrowTaskId != TASK_NONE)
+ {
+ RemoveScrollIndicatorArrowPair(sWonderNewsData->arrowTaskId);
+ sWonderNewsData->arrowTaskId = TASK_NONE;
+ }
+ break;
+ case 5:
+ PrintMysteryGiftOrEReaderTopMenu(gGiftIsFromEReader, flag);
+ MG_DrawCheckerboardPattern(3);
+ CopyBgTilemapBufferToVram(0);
+ CopyBgTilemapBufferToVram(3);
+ BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
+ break;
+ default:
+ if (UpdatePaletteFade())
+ return 0;
+ sWonderNewsData->enterExitState = 0;
+ return 1;
+ }
+ ++sWonderNewsData->enterExitState;
+ return 0;
+}
+
+void WonderNews_RemoveScrollIndicatorArrowPair(void)
+{
+ if (!sWonderNewsData->arrowsRemoved && sWonderNewsData->arrowTaskId != TASK_NONE)
+ {
+ RemoveScrollIndicatorArrowPair(sWonderNewsData->arrowTaskId);
+ sWonderNewsData->arrowTaskId = TASK_NONE;
+ sWonderNewsData->arrowsRemoved = TRUE;
+ }
+}
+
+
+void WonderNews_AddScrollIndicatorArrowPair(void)
+{
+ if (sWonderNewsData->arrowsRemoved)
+ {
+ sWonderNewsData->arrowTaskId = AddScrollIndicatorArrowPair(&sWonderNewsData->arrowsTemplate, &sWonderNewsData->scrollOffset);
+ sWonderNewsData->arrowsRemoved = FALSE;
+ }
+}
+
+u32 WonderNews_GetInput(u16 input)
+{
+ if (sWonderNewsData->scrolling)
+ {
+ UpdateNewsScroll();
+ return NEWS_INPUT_NONE;
+ }
+ switch (input)
+ {
+ case A_BUTTON:
+ return NEWS_INPUT_A;
+ case B_BUTTON:
+ return NEWS_INPUT_B;
+ case DPAD_UP:
+ if (sWonderNewsData->scrollOffset == 0)
+ return NEWS_INPUT_NONE;
+ if (sWonderNewsData->arrowsRemoved)
+ return NEWS_INPUT_NONE;
+ sWonderNewsData->scrollingDown = FALSE;
+ break;
+ case DPAD_DOWN:
+ if (sWonderNewsData->scrollOffset == sWonderNewsData->scrollEnd)
+ return NEWS_INPUT_NONE;
+ if (sWonderNewsData->arrowsRemoved)
+ return NEWS_INPUT_NONE;
+ sWonderNewsData->scrollingDown = TRUE;
+ break;
+ default:
+ return NEWS_INPUT_NONE;
+ }
+
+ // Init scroll
+ sWonderNewsData->scrolling = TRUE;
+ sWonderNewsData->scrollIncrement = 2;
+ sWonderNewsData->scrollTotal = 0;
+ if (!sWonderNewsData->scrollingDown)
+ return NEWS_INPUT_SCROLL_UP;
+ else
+ return NEWS_INPUT_SCROLL_DOWN;
+}
+
+static void BufferNewsText(void)
+{
+ u8 i = 0;
+ memcpy(sWonderNewsData->unk_01CE, sWonderNewsData->news.unk_04, WONDER_NEWS_TEXT_LENGTH);
+ sWonderNewsData->unk_01CE[WONDER_NEWS_TEXT_LENGTH] = EOS;
+ for (; i < 10; ++i)
+ {
+ memcpy(sWonderNewsData->unk_01F7[i], sWonderNewsData->news.unk_2C[i], WONDER_NEWS_TEXT_LENGTH);
+ sWonderNewsData->unk_01F7[i][WONDER_NEWS_TEXT_LENGTH] = EOS;
+ if (i > 7 && sWonderNewsData->unk_01F7[i][0] != EOS)
+ ++sWonderNewsData->scrollEnd;
+ }
+ sWonderNewsData->arrowsTemplate = sNews_ArrowsTemplate;
+ sWonderNewsData->arrowsTemplate.fullyDownThreshold = sWonderNewsData->scrollEnd;
+}
+
+static void DrawNewsWindows(void)
+{
+ u8 i = 0;
+ s32 x;
+ PutWindowTilemap(sWonderNewsData->windowIds[NEWS_WIN_0]);
+ PutWindowTilemap(sWonderNewsData->windowIds[NEWS_WIN_1]);
+ FillWindowPixelBuffer(sWonderNewsData->windowIds[NEWS_WIN_0], 0);
+ FillWindowPixelBuffer(sWonderNewsData->windowIds[NEWS_WIN_1], 0);
+ x = (224 - GetStringWidth(3, sWonderNewsData->unk_01CE, GetFontAttribute(3, FONTATTR_LETTER_SPACING))) / 2;
+ if (x < 0)
+ x = 0;
+ AddTextPrinterParameterized3(sWonderNewsData->windowIds[NEWS_WIN_0], 3, x, 6, sNews_TextColorTable[sWonderNewsData->gfx->textPal1], 0, sWonderNewsData->unk_01CE);
+ for (; i < 10; ++i)
+ AddTextPrinterParameterized3(sWonderNewsData->windowIds[NEWS_WIN_1], 3, 0, 16 * i + 2, sNews_TextColorTable[sWonderNewsData->gfx->textPal2], 0, sWonderNewsData->unk_01F7[i]);
+ CopyWindowToVram(sWonderNewsData->windowIds[NEWS_WIN_0], 3);
+ CopyWindowToVram(sWonderNewsData->windowIds[NEWS_WIN_1], 3);
+}
+
+static void UpdateNewsScroll(void)
+{
+ u16 bgMove = sWonderNewsData->scrollIncrement;
+ bgMove *= 256;
+ if (sWonderNewsData->scrollingDown)
+ {
+ ChangeBgY(2, bgMove, BG_COORD_ADD);
+ ChangeBgY(3, bgMove, BG_COORD_ADD);
+ }
+ else
+ {
+ ChangeBgY(2, bgMove, BG_COORD_SUB);
+ ChangeBgY(3, bgMove, BG_COORD_SUB);
+ }
+ sWonderNewsData->scrollTotal += sWonderNewsData->scrollIncrement;
+ if (sWonderNewsData->scrollTotal > 15)
+ {
+ if (sWonderNewsData->scrollingDown)
+ ++sWonderNewsData->scrollOffset;
+ else
+ --sWonderNewsData->scrollOffset;
+ sWonderNewsData->scrolling = FALSE;
+ sWonderNewsData->scrollTotal = 0;
+ }
+}