diff options
Diffstat (limited to 'src/easy_chat_3.c')
-rw-r--r-- | src/easy_chat_3.c | 2298 |
1 files changed, 2298 insertions, 0 deletions
diff --git a/src/easy_chat_3.c b/src/easy_chat_3.c new file mode 100644 index 000000000..1501762bc --- /dev/null +++ b/src/easy_chat_3.c @@ -0,0 +1,2298 @@ +#include "global.h" +#include "gflib.h" +#include "keyboard_text.h" +#include "decompress.h" +#include "easy_chat.h" +#include "graphics.h" +#include "menu.h" +#include "new_menu_helpers.h" +#include "strings.h" +#include "text_window.h" + +struct ECWork +{ + u16 state; + u16 windowId; + u16 id; + u8 frameAnimIdx; + u8 frameAnimTarget; + s8 frameAnimDelta; + u8 modeIconState; + u8 ecPrintBuffer[0xC1]; + u8 ecPaddedWordBuffer[0x200]; + u16 bg2ScrollRow; + int tgtBgY; + int deltaBgY; + struct Sprite * selectDestFieldCursorSprite; + struct Sprite * rectCursorSpriteRight; + struct Sprite * rectCursorSpriteLeft; + struct Sprite * selectWordCursorSprite; + struct Sprite * selectGroupHelpSprite; + struct Sprite * modeIconsSprite; + struct Sprite * upTriangleCursorSprite; + struct Sprite * downTriangleCursorSprite; + struct Sprite * startPgUpButtonSprite; + struct Sprite * selectPgDnButtonSprite; + u16 bg1TilemapBuffer[BG_SCREEN_SIZE / 2]; + u16 bg3TilemapBuffer[BG_SCREEN_SIZE / 2]; +}; + +struct EasyChatPhraseFrameDimensions +{ + u8 left; + u8 top; + u8 width; + u8 height; +}; + +static EWRAM_DATA struct ECWork * sEasyChatGraphicsResources = NULL; + +static bool8 ECInterfaceCmd_01(void); +static bool8 ECInterfaceCmd_02(void); +static bool8 ECInterfaceCmd_03(void); +static bool8 ECInterfaceCmd_05(void); +static bool8 ECInterfaceCmd_06(void); +static bool8 ECInterfaceCmd_04(void); +static bool8 ECInterfaceCmd_07(void); +static bool8 ECInterfaceCmd_08(void); +static bool8 ECInterfaceCmd_09(void); +static bool8 ECInterfaceCmd_10(void); +static bool8 ECInterfaceCmd_22(void); +static bool8 ECInterfaceCmd_14(void); +static bool8 ECInterfaceCmd_15(void); +static bool8 ECInterfaceCmd_16(void); +static bool8 ECInterfaceCmd_11(void); +static bool8 ECInterfaceCmd_12(void); +static bool8 ECInterfaceCmd_13(void); +static bool8 ECInterfaceCmd_17(void); +static bool8 ECInterfaceCmd_19(void); +static bool8 ECInterfaceCmd_18(void); +static bool8 ECInterfaceCmd_21(void); +static bool8 ECInterfaceCmd_20(void); +static bool8 InitEasyChatGraphicsWork_Internal(void); +static void SetGpuRegsForEasyChatInit(void); +static void LoadEasyChatPals(void); +static void PrintTitleText(void); +static void EC_AddTextPrinterParameterized2(u8 windowId, u8 fontId, const u8 *str, u8 left, u8 top, u8 speed, u8 bg, u8 fg, u8 shadow); +static void PrintECInstructionsText(void); +static void PrintECInterfaceTextById(u8 a0); +static void EC_CreateYesNoMenuWithInitialCursorPos(u8 initialCursorPos); +static void CreatePhraseFrameWindow(void); +static void PrintECFields(void); +static void DrawECFrameInTilemapBuffer(u16 *buffer); +static void PutWin2TilemapAndCopyToVram(void); +static void PrintECMenuById(u32 a0); +static void PrintECGroupOrAlphaMenu(void); +static void PrintECGroupsMenu(void); +static void PrintEasyChatKeyboardText(void); +static void PrintECWordsMenu(void); +static void UpdateWin2PrintWordsScrollDown(void); +static void UpdateWin2PrintWordsScrollUp(void); +static void UpdateWin2PrintWordsScrollPageDown(void); +static void UpdateWin2PrintWordsScrollPageUp(void); +static void PrintECRowsWin2(u8 row, u8 remrow); +static void ClearECRowsWin2(u8 row, u8 remrow); +static void ClearWin2AndCopyToVram(void); +static void StartWin2FrameAnim(int a0); +static bool8 AnimateFrameResize(void); +static void RedrawFrameByIndex(u8 a0); +static void RedrawFrameByRect(int left, int top, int width, int height); +static void InitBg2Scroll(void); +static void ScheduleBg2VerticalScroll(s16 direction, u8 speed); +static bool8 AnimateBg2VerticalScroll(void); +static int GetBg2ScrollRow(void); +static void SetRegWin0Coords(u8 left, u8 top, u8 right, u8 bottom); +static void LoadSpriteGfx(void); +static void CreateSelectDestFieldCursorSprite(void); +static void SpriteCB_BounceCursor(struct Sprite * sprite); +static void SetSelectDestFieldCursorSpritePosAndResetAnim(u8 x, u8 y); +static void FreezeSelectDestFieldCursorSprite(void); +static void UnfreezeSelectDestFieldCursorSprite(void); +static void CreateRedRectangularCursorSpritePair(void); +static void DestroyRedRectangularCursor(void); +static void EC_MoveCursor(void); +static void MoveCursor_Group(s8 a0, s8 a1); +static void MoveCursor_Alpha(s8 a0, s8 a1); +static void CreateSelectWordCursorSprite(void); +static void SpriteCB_SelectWordCursorSprite(struct Sprite * sprite); +static void SetSelectWordCursorSpritePos(void); +static void SetSelectWordCursorSpritePosExplicit(u8 x, u8 y); +static void DestroySelectWordCursorSprite(void); +static void CreateSelectGroupHelpSprite(void); +static bool8 AnimateSeletGroupModeAndHelpSpriteEnter(void); +static void StartModeIconHidingAnimation(void); +static bool8 RunModeIconHidingAnimation(void); +static void ShrinkModeIconsSprite(void); +static void ShowModeIconsSprite(void); +static bool8 ModeIconsSpriteAnimIsEnded(void); +static void CreateVerticalScrollArrowSprites(void); +static void UpdateVerticalScrollArrowVisibility(void); +static void HideVerticalScrollArrowSprites(void); +static void UpdateVerticalScrollArrowSpriteXPos(int a0); +static void CreateStartSelectButtonsSprites(void); +static void UpdateStartSelectButtonSpriteVisibility(void); +static void HideStartSelectButtonSprites(void); +static void CreateFooterWindow(void); + +static const u16 gUnknown_843F3B8[] = INCBIN_U16("graphics/link_rfu/unk_843F3F8.gbapal"); +static const u16 gUnknown_843F3D8[] = INCBIN_U16("graphics/link_rfu/unk_8E9BD28.gbapal"); +static const u16 sRightTriangleCursor_Tiles[] = INCBIN_U16("graphics/link_rfu/unk_843F3F8.4bpp"); +static const u16 sUpTriangleCursor_Tiles[] = INCBIN_U16("graphics/link_rfu/unk_843F418.4bpp"); +static const u16 sStartSelectButtons_Tiles[] = INCBIN_U16("graphics/link_rfu/unk_843F518.4bpp"); +static const u16 gUnknown_843F618[] = INCBIN_U16("graphics/link_rfu/unk_843F638.gbapal"); +static const u32 gUnknown_843F638[] = INCBIN_U32("graphics/link_rfu/unk_843F638.4bpp.lz"); +static const u16 gUnknown_843F76C[] = INCBIN_U16("graphics/link_rfu/unk_843F76C.gbapal"); +static const u16 gUnknown_843F78C[] = INCBIN_U16("graphics/link_rfu/unk_843F78C.gbapal"); +static const u32 gUnknown_843F7AC[] = INCBIN_U32("graphics/link_rfu/unk_843F7AC.4bpp.lz"); + +static const u16 gUnknown_843F874[] = { + RGB( 0, 0, 0), + RGB( 0, 0, 0), + RGB( 7, 25, 31), + RGB(21, 21, 29) +}; + +static const u16 gUnknown_843F87C[] = { + RGB( 0, 0, 0), + RGB(31, 31, 31), + RGB(12, 12, 12), + RGB(27, 26, 27), + RGB( 8, 17, 9) +}; + +static const struct EasyChatPhraseFrameDimensions sPhraseFrameDimensions[] = { + { + .left = 0x03, + .top = 0x04, + .width = 0x18, + .height = 0x04 + }, { + .left = 0x01, + .top = 0x04, + .width = 0x1b, + .height = 0x04 + }, { + .left = 0x03, + .top = 0x00, + .width = 0x18, + .height = 0x0a + }, { + .left = 0x06, + .top = 0x06, + .width = 0x12, + .height = 0x04 + }, { + .left = 0x10, + .top = 0x04, + .width = 0x09, + .height = 0x02 + }, { + .left = 0x0e, + .top = 0x04, + .width = 0x12, + .height = 0x04 + } +}; + +static const struct BgTemplate sEasyChatBgTemplates[] = { + { + .bg = 0, + .charBaseIndex = 0, + .mapBaseIndex = 28, + .screenSize = 0, + .paletteMode = 0, + .priority = 0, + .baseTile = 0, + }, { + .bg = 1, + .charBaseIndex = 3, + .mapBaseIndex = 29, + .screenSize = 0, + .paletteMode = 0, + .priority = 1, + .baseTile = 0, + }, { + .bg = 2, + .charBaseIndex = 0, + .mapBaseIndex = 30, + .screenSize = 0, + .paletteMode = 0, + .priority = 2, + .baseTile = 0x80, + }, { + .bg = 3, + .charBaseIndex = 2, + .mapBaseIndex = 31, + .screenSize = 0, + .paletteMode = 0, + .priority = 3, + .baseTile = 0, + } +}; + +static const struct WindowTemplate sEasyChatWindowTemplates[] = { + { + .bg = 1, + .tilemapLeft = 7, + .tilemapTop = 0, + .width = 16, + .height = 2, + .paletteNum = 10, + .baseBlock = 0x10, + }, + { + .bg = 0, + .tilemapLeft = 4, + .tilemapTop = 15, + .width = 22, + .height = 4, + .paletteNum = 15, + .baseBlock = 0xA, + }, + { + .bg = 2, + .tilemapLeft = 1, + .tilemapTop = 0, + .width = 28, + .height = 32, + .paletteNum = 3, + .baseBlock = 0, + }, + DUMMY_WIN_TEMPLATE, +}; + +static const struct WindowTemplate sEasyChatYesNoWindowTemplate = { + .bg = 0, + .tilemapLeft = 22, + .tilemapTop = 9, + .width = 5, + .height = 4, + .paletteNum = 15, + .baseBlock = 0x062 +}; + +static const u8 gUnknown_843F8D8[] = _("{UNDERSCORE}"); +static const u8 sText_Clear17[] = _("{CLEAR 17}"); + +static const u8 *const sEasyChatKeyboardText[] = { + gUnknown_847A8D8, + gUnknown_847A8FA, + gUnknown_847A913, + gUnknown_847A934 +}; + +static const struct SpriteSheet sEasyChatSpriteSheets[] = { + {sRightTriangleCursor_Tiles, 0x0020, 0}, + {sUpTriangleCursor_Tiles, 0x0100, 2}, + {sStartSelectButtons_Tiles, 0x0100, 3}, + {} +}; + +static const struct SpritePalette sEasyChatSpritePalettes[] = { + {gUnknown_843F3B8, 0}, + {gUnknown_843F3D8, 1}, + {gUnknown_8E99F24, 2}, + {gUnknown_843F618, 3}, + {} +}; + +static const struct CompressedSpriteSheet sEasyChatCompressedSpriteSheets[] = { + {gUnknown_843F638, 0x0800, 5}, + {gEasyChatRedRectangularCursor_Tiles, 0x1000, 1}, + {gEasyChatSelectGroupHelp_Tiles, 0x0800, 6}, + {gEasyChatModeIcons_Tiles, 0x1000, 4} +}; + +static const u8 sECDisplay_AlphaModeXCoords[] = { + 0, + 12, + 24, + 56, + 68, + 80, + 92 +}; + +static const struct OamData sOamData_RightTriangleCursor = { + .y = 0, + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .bpp = ST_OAM_4BPP, + .mosaic = FALSE, + .shape = SPRITE_SHAPE(8x8), + .x = 0, + .matrixNum = 0, + .size = SPRITE_SIZE(8x8), + .tileNum = 0x000, + .priority = 3, + .paletteNum = 0 +}; + +static const struct SpriteTemplate sSpriteTemplate_RightTriangleCursor = { + .tileTag = 0, + .paletteTag = 0, + .oam = &sOamData_RightTriangleCursor, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_BounceCursor +}; + +static const struct OamData sOamData_RedRectangularCursor = { + .y = 0, + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .bpp = ST_OAM_4BPP, + .mosaic = FALSE, + .shape = SPRITE_SHAPE(64x32), + .x = 0, + .matrixNum = 0, + .size = SPRITE_SIZE(64x32), + .tileNum = 0x000, + .priority = 1, + .paletteNum = 0 +}; + +static const union AnimCmd sAnimCmd_RectCursor_Wide[] = { + ANIMCMD_FRAME(0x00, 0), + ANIMCMD_END +}; + +static const union AnimCmd sAnimCmd_RectCursor_Norm[] = { + ANIMCMD_FRAME(0x20, 0), + ANIMCMD_END +}; + +static const union AnimCmd sAnimCmd_RectCursor_NormTaller[] = { + ANIMCMD_FRAME(0x40, 0), + ANIMCMD_END +}; + +static const union AnimCmd sAnimCmd_RectCursor_Narrow[] = { + ANIMCMD_FRAME(0x60, 0), + ANIMCMD_END +}; + +static const union AnimCmd *const sAnimTable_RedRectangularCursor[] = { + sAnimCmd_RectCursor_Wide, + sAnimCmd_RectCursor_Norm, + sAnimCmd_RectCursor_NormTaller, + sAnimCmd_RectCursor_Narrow +}; + +static const struct SpriteTemplate sSpriteTemplate_RedRectangularCursor = { + .tileTag = 1, + .paletteTag = 1, + .oam = &sOamData_RedRectangularCursor, + .anims = sAnimTable_RedRectangularCursor, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_BounceCursor +}; + +static const struct OamData sOamData_EasyChatModeIcons = { + .y = 0, + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .bpp = ST_OAM_4BPP, + .mosaic = FALSE, + .shape = SPRITE_SHAPE(64x32), + .x = 0, + .matrixNum = 0, + .size = SPRITE_SIZE(64x32), + .tileNum = 0x000, + .priority = 1, + .paletteNum = 0 +}; + +static const union AnimCmd sAnim_EasyChatModeIcon_Hidden[] = { + ANIMCMD_FRAME(0x60, 0), + ANIMCMD_END +}; + +static const union AnimCmd sAnim_EasyChatModeIcon_ToGroupMode[] = { + ANIMCMD_FRAME(0x40, 4), + ANIMCMD_FRAME(0x20, 4), + ANIMCMD_END +}; + +static const union AnimCmd sAnim_EasyChatModeIcon_ToAlphaMode[] = { + ANIMCMD_FRAME(0x40, 4), + ANIMCMD_FRAME(0x00, 4), + ANIMCMD_END +}; + +static const union AnimCmd sAnim_EasyChatModeIcon_ToHidden[] = { + ANIMCMD_FRAME(0x40, 4), + ANIMCMD_FRAME(0x60, 0), + ANIMCMD_END +}; + +static const union AnimCmd sAnim_EasyChatModeIcon_HoldSmall[] = { + ANIMCMD_FRAME(0x40, 4), + ANIMCMD_END +}; + +static const union AnimCmd *const sAnimTable_EasyChatModeIcons[] = { + sAnim_EasyChatModeIcon_Hidden, + sAnim_EasyChatModeIcon_ToGroupMode, + sAnim_EasyChatModeIcon_ToAlphaMode, + sAnim_EasyChatModeIcon_ToHidden, + sAnim_EasyChatModeIcon_HoldSmall +}; + +static const struct SpriteTemplate sSpriteTemplate_EasyChatModeIcons = { + .tileTag = 4, + .paletteTag = 2, + .oam = &sOamData_EasyChatModeIcons, + .anims = sAnimTable_EasyChatModeIcons, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy +}; + +static const struct OamData sOamData_SelectGroupHelp = { + .y = 0, + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .mosaic = FALSE, + .bpp = ST_OAM_4BPP, + .shape = SPRITE_SHAPE(64x64), + .x = 0, + .matrixNum = 0, + .size = SPRITE_SIZE(64x64), + .tileNum = 0x000, + .priority = 3, + .paletteNum = 0 +}; + +static const struct SpriteTemplate sSpriteTemplate_SelectGroupHelp = { + .tileTag = 6, + .paletteTag = 2, + .oam = &sOamData_SelectGroupHelp, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy +}; + +static const struct OamData gUnknown_843FA58 = { + .y = 0, + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .mosaic = FALSE, + .bpp = ST_OAM_4BPP, + .shape = SPRITE_SHAPE(32x8), + .x = 0, + .matrixNum = 0, + .size = SPRITE_SIZE(32x8), + .tileNum = 0x000, + .priority = 1, + .paletteNum = 0 +}; + +static const struct OamData sOamData_UpTriangleCursor = { + .y = 0, + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .mosaic = FALSE, + .bpp = ST_OAM_4BPP, + .shape = SPRITE_SHAPE(16x16), + .x = 0, + .matrixNum = 0, + .size = SPRITE_SIZE(16x16), + .tileNum = 0x000, + .priority = 1, + .paletteNum = 0 +}; + +static const union AnimCmd gUnknown_843FA68[] = { + ANIMCMD_FRAME(0, 0), + ANIMCMD_END, +}; + +static const union AnimCmd gUnknown_843FA70[] = { + ANIMCMD_FRAME(4, 0), + ANIMCMD_END, +}; + +static const union AnimCmd *const gUnknown_843FA78[] = { + gUnknown_843FA68, + gUnknown_843FA70, +}; + +static const struct SpriteTemplate sSpriteTemplate_StartSelectButtons = { + .tileTag = 3, + .paletteTag = 2, + .oam = &gUnknown_843FA58, + .anims = gUnknown_843FA78, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +static const struct SpriteTemplate sSpriteTemplate_UpTriangleCursor = { + .tileTag = 2, + .paletteTag = 2, + .oam = &sOamData_UpTriangleCursor, + .anims = gUnknown_843FA78, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +bool8 InitEasyChatGraphicsWork(void) +{ + if (!InitEasyChatGraphicsWork_Internal()) + return FALSE; + else + return TRUE; +} + +bool8 LoadEasyChatGraphics(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(0, sEasyChatBgTemplates, NELEMS(sEasyChatBgTemplates)); + SetBgTilemapBuffer(3, sEasyChatGraphicsResources->bg3TilemapBuffer); + SetBgTilemapBuffer(1, sEasyChatGraphicsResources->bg1TilemapBuffer); + InitWindows(sEasyChatWindowTemplates); + DeactivateAllTextPrinters(); + LoadEasyChatPals(); + SetGpuRegsForEasyChatInit(); + CpuFastFill(0, (void *)VRAM + 0x1000000, 0x400); + break; + case 1: + DecompressAndLoadBgGfxUsingHeap(3, gEasyChatWindow_Gfx, 0, 0, 0); + CopyToBgTilemapBuffer(3, gEasyChatWindow_Tilemap, 0, 0); + CreatePhraseFrameWindow(); + CreateFooterWindow(); + CopyBgTilemapBufferToVram(3); + break; + case 2: + DrawECFrameInTilemapBuffer(sEasyChatGraphicsResources->bg1TilemapBuffer); + DecompressAndLoadBgGfxUsingHeap(1, gUnknown_843F7AC, 0, 0, 0); + CopyBgTilemapBufferToVram(1); + break; + case 3: + PrintTitleText(); + PrintECInstructionsText(); + PrintECFields(); + PutWin2TilemapAndCopyToVram(); + break; + case 4: + LoadSpriteGfx(); + CreateSelectDestFieldCursorSprite(); + break; + case 5: + if (IsDma3ManagerBusyWithBgCopy()) + { + return TRUE; + } + else + { + SetRegWin0Coords(0, 0, 0, 0); + SetGpuReg(REG_OFFSET_WININ, WIN_RANGE(0, 63)); + SetGpuReg(REG_OFFSET_WINOUT, WIN_RANGE(0, 59)); + ShowBg(3); + ShowBg(1); + ShowBg(2); + ShowBg(0); + CreateVerticalScrollArrowSprites(); + CreateStartSelectButtonsSprites(); + } + break; + default: + return FALSE; + } + + sEasyChatGraphicsResources->state++; + return TRUE; +} + +void DestroyEasyChatGraphicsResources(void) +{ + if (sEasyChatGraphicsResources) + Free(sEasyChatGraphicsResources); +} + +void EasyChatInterfaceCommand_Setup(u16 id) +{ + sEasyChatGraphicsResources->id = id; + sEasyChatGraphicsResources->state = 0; + EasyChatInterfaceCommand_Run(); +} + +bool8 EasyChatInterfaceCommand_Run(void) +{ + switch (sEasyChatGraphicsResources->id) + { + case 0: return FALSE; + case 1: return ECInterfaceCmd_01(); + case 2: return ECInterfaceCmd_02(); + case 3: return ECInterfaceCmd_03(); + case 4: return ECInterfaceCmd_04(); + case 5: return ECInterfaceCmd_05(); + case 6: return ECInterfaceCmd_06(); + case 7: return ECInterfaceCmd_07(); + case 8: return ECInterfaceCmd_08(); + case 9: return ECInterfaceCmd_09(); + case 10: return ECInterfaceCmd_10(); + case 11: return ECInterfaceCmd_11(); + case 12: return ECInterfaceCmd_12(); + case 13: return ECInterfaceCmd_13(); + case 14: return ECInterfaceCmd_14(); + case 15: return ECInterfaceCmd_15(); + case 16: return ECInterfaceCmd_16(); + case 17: return ECInterfaceCmd_17(); + case 18: return ECInterfaceCmd_18(); + case 19: return ECInterfaceCmd_19(); + case 20: return ECInterfaceCmd_20(); + case 21: return ECInterfaceCmd_21(); + case 22: return ECInterfaceCmd_22(); + default: return FALSE; + } +} + +static bool8 ECInterfaceCmd_01(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + PrintECFields(); + sEasyChatGraphicsResources->state++; + break; + case 1: + return IsDma3ManagerBusyWithBgCopy(); + } + + return TRUE; +} + +static bool8 ECInterfaceCmd_02(void) +{ + u8 i; + u16 *ecWordBuffer; + u16 *ecWord; + u8 frameId; + u8 cursorColumn, cursorRow, numColumns; + s16 var1; + int stringWidth; + int trueStringWidth; + int var2; + u8 str[64]; + + ecWordBuffer = GetEasyChatWordBuffer(); + frameId = GetEasyChatScreenFrameId(); + cursorColumn = GetMainCursorColumn(); + cursorRow = GetMainCursorRow(); + numColumns = GetNumColumns(); + ecWord = &ecWordBuffer[cursorRow * numColumns]; + var1 = 8 * sPhraseFrameDimensions[frameId].left + 13; + for (i = 0; i < cursorColumn; i++) + { + if (*ecWord == 0xFFFF) + { + stringWidth = GetStringWidth(1, gUnknown_843F8D8, 0) * 7; + } + else + { + CopyEasyChatWord(str, *ecWord); + stringWidth = GetStringWidth(1, str, 0); + } + + trueStringWidth = stringWidth + 17; + var1 += trueStringWidth; + ecWord++; + } + + var2 = 8 * (sPhraseFrameDimensions[frameId].top + cursorRow * 2 + 1) + 1; + SetSelectDestFieldCursorSpritePosAndResetAnim(var1, var2); + return FALSE; +} + +static bool8 ECInterfaceCmd_03(void) +{ + u8 xOffset; + switch (GetMainCursorColumn()) + { + case 0: + xOffset = 28; + break; + case 1: + xOffset = 115; + break; + case 2: + xOffset = 191; + break; + default: + return FALSE; + } + SetSelectDestFieldCursorSpritePosAndResetAnim(xOffset, 97); + return FALSE; +} + +static bool8 ECInterfaceCmd_05(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + FreezeSelectDestFieldCursorSprite(); + PrintECInterfaceTextById(2); + EC_CreateYesNoMenuWithInitialCursorPos(1); + sEasyChatGraphicsResources->state++; + break; + case 1: + return IsDma3ManagerBusyWithBgCopy(); + } + + return TRUE; +} + +static bool8 ECInterfaceCmd_06(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + FreezeSelectDestFieldCursorSprite(); + PrintECInterfaceTextById(3); + EC_CreateYesNoMenuWithInitialCursorPos(0); + sEasyChatGraphicsResources->state++; + break; + case 1: + return IsDma3ManagerBusyWithBgCopy(); + } + + return TRUE; +} + +static bool8 ECInterfaceCmd_04(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + FreezeSelectDestFieldCursorSprite(); + PrintECInterfaceTextById(1); + EC_CreateYesNoMenuWithInitialCursorPos(1); + sEasyChatGraphicsResources->state++; + break; + case 1: + return IsDma3ManagerBusyWithBgCopy(); + } + + return TRUE; +} + +static bool8 ECInterfaceCmd_07(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + UnfreezeSelectDestFieldCursorSprite(); + PrintECInterfaceTextById(0); + ShowBg(0); + sEasyChatGraphicsResources->state++; + break; + case 1: + return IsDma3ManagerBusyWithBgCopy(); + } + + return TRUE; +} + +static bool8 ECInterfaceCmd_08(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + UnfreezeSelectDestFieldCursorSprite(); + PrintECInterfaceTextById(0); + PrintECFields(); + sEasyChatGraphicsResources->state++; + // Fall through + case 1: + return IsDma3ManagerBusyWithBgCopy(); + } + + return TRUE; +} + +static bool8 ECInterfaceCmd_09(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + FreezeSelectDestFieldCursorSprite(); + HideBg(0); + SetRegWin0Coords(0, 0, 0, 0); + PrintECGroupOrAlphaMenu(); + sEasyChatGraphicsResources->state++; + break; + case 1: + if (!IsDma3ManagerBusyWithBgCopy()) + { + StartWin2FrameAnim(0); + sEasyChatGraphicsResources->state++; + } + break; + case 2: + if (!IsDma3ManagerBusyWithBgCopy() && !AnimateFrameResize()) + sEasyChatGraphicsResources->state++; + break; + case 3: + if (!IsDma3ManagerBusyWithBgCopy()) + { + CreateSelectGroupHelpSprite(); + sEasyChatGraphicsResources->state++; + } + break; + case 4: + if (!AnimateSeletGroupModeAndHelpSpriteEnter()) + { + CreateRedRectangularCursorSpritePair(); + UpdateVerticalScrollArrowSpriteXPos(0); + UpdateVerticalScrollArrowVisibility(); + sEasyChatGraphicsResources->state++; + return FALSE; + } + break; + default: + return FALSE; + } + + return TRUE; +} + +static bool8 ECInterfaceCmd_10(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + DestroyRedRectangularCursor(); + StartModeIconHidingAnimation(); + HideVerticalScrollArrowSprites(); + sEasyChatGraphicsResources->state++; + break; + case 1: + if (RunModeIconHidingAnimation() == TRUE) + break; + + StartWin2FrameAnim(1); + sEasyChatGraphicsResources->state++; + // Fall through + case 2: + if (!AnimateFrameResize()) + sEasyChatGraphicsResources->state++; + break; + case 3: + if (!IsDma3ManagerBusyWithBgCopy()) + { + UnfreezeSelectDestFieldCursorSprite(); + ShowBg(0); + sEasyChatGraphicsResources->state++; + } + break; + case 4: + return FALSE; + } + + return TRUE; +} + +static bool8 ECInterfaceCmd_22(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + DestroyRedRectangularCursor(); + HideVerticalScrollArrowSprites(); + ShrinkModeIconsSprite(); + StartWin2FrameAnim(5); + sEasyChatGraphicsResources->state++; + break; + case 1: + if (!AnimateFrameResize() && !ModeIconsSpriteAnimIsEnded()) + { + PrintECGroupOrAlphaMenu(); + sEasyChatGraphicsResources->state++; + } + break; + case 2: + if (!IsDma3ManagerBusyWithBgCopy()) + { + StartWin2FrameAnim(6); + ShowModeIconsSprite(); + sEasyChatGraphicsResources->state++; + } + break; + case 3: + if (!AnimateFrameResize() && !ModeIconsSpriteAnimIsEnded()) + { + UpdateVerticalScrollArrowVisibility(); + CreateRedRectangularCursorSpritePair(); + sEasyChatGraphicsResources->state++; + return FALSE; + } + break; + case 4: + return FALSE; + } + + return TRUE; +} + +static bool8 ECInterfaceCmd_14(void) +{ + EC_MoveCursor(); + return FALSE; +} + +static bool8 ECInterfaceCmd_15(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + ScheduleBg2VerticalScroll(1, 2); + sEasyChatGraphicsResources->state++; + // Fall through + case 1: + if (!AnimateBg2VerticalScroll()) + { + EC_MoveCursor(); + UpdateVerticalScrollArrowVisibility(); + return FALSE; + } + break; + } + + return TRUE; +} + +static bool8 ECInterfaceCmd_16(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + ScheduleBg2VerticalScroll(-1, 2); + sEasyChatGraphicsResources->state++; + // Fall through + case 1: + if (!AnimateBg2VerticalScroll()) + { + UpdateVerticalScrollArrowVisibility(); + sEasyChatGraphicsResources->state++; + return FALSE; + } + break; + case 2: + return FALSE; + } + + return TRUE; +} + +static bool8 ECInterfaceCmd_11(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + DestroyRedRectangularCursor(); + StartModeIconHidingAnimation(); + HideVerticalScrollArrowSprites(); + sEasyChatGraphicsResources->state++; + break; + case 1: + if (!RunModeIconHidingAnimation()) + { + ClearWin2AndCopyToVram(); + sEasyChatGraphicsResources->state++; + } + break; + case 2: + if (!IsDma3ManagerBusyWithBgCopy()) + { + StartWin2FrameAnim(2); + sEasyChatGraphicsResources->state++; + } + break; + case 3: + if (!AnimateFrameResize()) + { + PrintECMenuById(2); + sEasyChatGraphicsResources->state++; + } + break; + case 4: + if (!IsDma3ManagerBusyWithBgCopy()) + { + CreateSelectWordCursorSprite(); + UpdateVerticalScrollArrowSpriteXPos(1); + UpdateVerticalScrollArrowVisibility(); + UpdateStartSelectButtonSpriteVisibility(); + sEasyChatGraphicsResources->state++; + return FALSE; + } + break; + case 5: + return FALSE; + } + + return TRUE; +} + +static bool8 ECInterfaceCmd_12(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + PrintECFields(); + sEasyChatGraphicsResources->state++; + break; + case 1: + DestroySelectWordCursorSprite(); + HideVerticalScrollArrowSprites(); + HideStartSelectButtonSprites(); + ClearWin2AndCopyToVram(); + sEasyChatGraphicsResources->state++; + break; + case 2: + if (!IsDma3ManagerBusyWithBgCopy()) + { + StartWin2FrameAnim(3); + sEasyChatGraphicsResources->state++; + } + break; + case 3: + if (!AnimateFrameResize()) + { + ShowBg(0); + sEasyChatGraphicsResources->state++; + } + break; + case 4: + if (!IsDma3ManagerBusyWithBgCopy()) + { + UnfreezeSelectDestFieldCursorSprite(); + sEasyChatGraphicsResources->state++; + return FALSE; + } + break; + case 5: + return FALSE; + } + + return TRUE; +} + +static bool8 ECInterfaceCmd_13(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + DestroySelectWordCursorSprite(); + HideVerticalScrollArrowSprites(); + HideStartSelectButtonSprites(); + ClearWin2AndCopyToVram(); + sEasyChatGraphicsResources->state++; + break; + case 1: + if (!IsDma3ManagerBusyWithBgCopy()) + { + StartWin2FrameAnim(4); + sEasyChatGraphicsResources->state++; + } + break; + case 2: + if (!AnimateFrameResize()) + { + PrintECGroupOrAlphaMenu(); + sEasyChatGraphicsResources->state++; + } + break; + case 3: + if (!IsDma3ManagerBusyWithBgCopy()) + { + CreateSelectGroupHelpSprite(); + sEasyChatGraphicsResources->state++; + } + break; + case 4: + if (!AnimateSeletGroupModeAndHelpSpriteEnter()) + { + CreateRedRectangularCursorSpritePair(); + UpdateVerticalScrollArrowSpriteXPos(0); + UpdateVerticalScrollArrowVisibility(); + sEasyChatGraphicsResources->state++; + return FALSE; + } + break; + } + + return TRUE; +} + +static bool8 ECInterfaceCmd_17(void) +{ + SetSelectWordCursorSpritePos(); + return FALSE; +} + +static bool8 ECInterfaceCmd_19(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + UpdateWin2PrintWordsScrollDown(); + sEasyChatGraphicsResources->state++; + break; + case 1: + if (!IsDma3ManagerBusyWithBgCopy()) + { + ScheduleBg2VerticalScroll(1, 2); + sEasyChatGraphicsResources->state++; + } + break; + case 2: + if (!AnimateBg2VerticalScroll()) + { + SetSelectWordCursorSpritePos(); + UpdateVerticalScrollArrowVisibility(); + UpdateStartSelectButtonSpriteVisibility(); + sEasyChatGraphicsResources->state++; + return FALSE; + } + break; + case 3: + return FALSE; + } + + return TRUE; +} + +static bool8 ECInterfaceCmd_18(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + UpdateWin2PrintWordsScrollUp(); + sEasyChatGraphicsResources->state++; + break; + case 1: + if (!IsDma3ManagerBusyWithBgCopy()) + { + ScheduleBg2VerticalScroll(-1, 2); + sEasyChatGraphicsResources->state++; + } + break; + case 2: + if (!AnimateBg2VerticalScroll()) + { + UpdateVerticalScrollArrowVisibility(); + UpdateStartSelectButtonSpriteVisibility(); + sEasyChatGraphicsResources->state++; + return FALSE; + } + break; + case 3: + return FALSE; + } + + return TRUE; +} + +static bool8 ECInterfaceCmd_21(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + UpdateWin2PrintWordsScrollPageDown(); + sEasyChatGraphicsResources->state++; + break; + case 1: + if (!IsDma3ManagerBusyWithBgCopy()) + { + s16 direction = GetECSelectWordRowsAbove() - GetBg2ScrollRow(); + ScheduleBg2VerticalScroll(direction, 4); + sEasyChatGraphicsResources->state++; + } + break; + case 2: + if (!AnimateBg2VerticalScroll()) + { + SetSelectWordCursorSpritePos(); + UpdateVerticalScrollArrowVisibility(); + UpdateStartSelectButtonSpriteVisibility(); + sEasyChatGraphicsResources->state++; + return FALSE; + } + break; + case 3: + return FALSE; + } + + return TRUE; +} + +static bool8 ECInterfaceCmd_20(void) +{ + switch (sEasyChatGraphicsResources->state) + { + case 0: + UpdateWin2PrintWordsScrollPageUp(); + sEasyChatGraphicsResources->state++; + break; + case 1: + if (!IsDma3ManagerBusyWithBgCopy()) + { + s16 direction = GetECSelectWordRowsAbove() - GetBg2ScrollRow(); + ScheduleBg2VerticalScroll(direction, 4); + sEasyChatGraphicsResources->state++; + } + break; + case 2: + if (!AnimateBg2VerticalScroll()) + { + UpdateVerticalScrollArrowVisibility(); + UpdateStartSelectButtonSpriteVisibility(); + sEasyChatGraphicsResources->state++; + return FALSE; + } + break; + case 3: + return FALSE; + } + + return TRUE; +} + +static bool8 InitEasyChatGraphicsWork_Internal(void) +{ + sEasyChatGraphicsResources = Alloc(sizeof(*sEasyChatGraphicsResources)); + if (sEasyChatGraphicsResources == NULL) + return FALSE; + + sEasyChatGraphicsResources->state = 0; + sEasyChatGraphicsResources->selectDestFieldCursorSprite = NULL; + sEasyChatGraphicsResources->rectCursorSpriteRight = NULL; + sEasyChatGraphicsResources->rectCursorSpriteLeft = NULL; + sEasyChatGraphicsResources->selectWordCursorSprite = NULL; + sEasyChatGraphicsResources->selectGroupHelpSprite = NULL; + sEasyChatGraphicsResources->modeIconsSprite = NULL; + sEasyChatGraphicsResources->upTriangleCursorSprite = NULL; + sEasyChatGraphicsResources->downTriangleCursorSprite = NULL; + sEasyChatGraphicsResources->startPgUpButtonSprite = NULL; + sEasyChatGraphicsResources->selectPgDnButtonSprite = NULL; + return TRUE; +} + +static void SetGpuRegsForEasyChatInit(void) +{ + ChangeBgX(3, 0, 0); + ChangeBgY(3, 0, 0); + ChangeBgX(1, 0, 0); + ChangeBgY(1, 0, 0); + ChangeBgX(2, 0, 0); + ChangeBgY(2, 0, 0); + ChangeBgX(0, 0, 0); + ChangeBgY(0, 0, 0); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON | DISPCNT_WIN0_ON); +} + +static void LoadEasyChatPals(void) +{ + ResetPaletteFade(); + LoadPalette(gEasyChatMode_Pal, 0, 32); + LoadPalette(gUnknown_843F76C, 1 * 16, 32); + LoadPalette(gUnknown_843F78C, 4 * 16, 32); + LoadPalette(gUnknown_843F874, 10 * 16, 8); + LoadPalette(gUnknown_843F87C, 11 * 16, 10); + LoadPalette(gUnknown_843F87C, 15 * 16, 10); + LoadPalette(gUnknown_843F87C, 3 * 16, 10); +} + +static void PrintTitleText(void) +{ + int xOffset; + const u8 *titleText = GetTitleText(); + if (titleText == NULL) + return; + + xOffset = (128 - GetStringWidth(1, titleText, 0)) / 2u; + FillWindowPixelBuffer(0, PIXEL_FILL(0)); + EC_AddTextPrinterParameterized2(0, 1, titleText, xOffset, 0, TEXT_SPEED_FF, TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GREY, TEXT_COLOR_LIGHT_GREY); + PutWindowTilemap(0); + CopyWindowToVram(0, 3); +} + +static void EC_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str, u8 x, u8 y, u8 speed, void (*callback)(struct TextPrinterTemplate *, u16)) +{ + if (fontId == 1) y += 2; + AddTextPrinterParameterized(windowId, fontId, str, x, y, speed, callback); +} + +static void EC_AddTextPrinterParameterized2(u8 windowId, u8 fontId, const u8 *str, u8 x, u8 y, u8 speed, u8 bg, u8 fg, u8 shadow) +{ + u8 color[3]; + if (fontId == 1) y += 2; + color[0] = bg; + color[1] = fg; + color[2] = shadow; + AddTextPrinterParameterized3(windowId, fontId, x, y, color, speed, str); +} + +static void PrintECInstructionsText(void) +{ + FillBgTilemapBufferRect(0, 0, 0, 0, 32, 20, 17); + TextWindow_SetUserSelectedFrame(1, 1, 0xE0); + DrawTextBorderOuter(1, 1, 14); + PrintECInterfaceTextById(0); + PutWindowTilemap(1); + CopyBgTilemapBufferToVram(0); +} + +static void PrintECInterfaceTextById(u8 direction) +{ + const u8 *text2 = NULL; + const u8 *text1 = NULL; + switch (direction) + { + case 0: + GetEasyChatInstructionsText(&text1, &text2); + break; + case 2: + GetEasyChatConfirmCancelText(&text1, &text2); + break; + case 3: + GetEasyChatConfirmText(&text1, &text2); + break; + case 1: + GetEasyChatConfirmDeletionText(&text1, &text2); + break; + } + + FillWindowPixelBuffer(1, PIXEL_FILL(1)); + if (text1) + EC_AddTextPrinterParameterized(1, 1, text1, 0, 0, TEXT_SPEED_FF, NULL); + + if (text2) + EC_AddTextPrinterParameterized(1, 1, text2, 0, 16, TEXT_SPEED_FF, NULL); + + CopyWindowToVram(1, 3); +} + +static void EC_CreateYesNoMenuWithInitialCursorPos(u8 initialCursorPos) +{ + CreateYesNoMenu(&sEasyChatYesNoWindowTemplate, 1, 0, 2, 0x001, 14, initialCursorPos); +} + +static void CreatePhraseFrameWindow(void) +{ + u8 frameId; + struct WindowTemplate template; + + frameId = GetEasyChatScreenFrameId(); + template.bg = 3; + template.tilemapLeft = sPhraseFrameDimensions[frameId].left; + template.tilemapTop = sPhraseFrameDimensions[frameId].top; + template.width = sPhraseFrameDimensions[frameId].width; + template.height = sPhraseFrameDimensions[frameId].height; + template.paletteNum = 11; + template.baseBlock = 0x060; + sEasyChatGraphicsResources->windowId = AddWindow(&template); + PutWindowTilemap(sEasyChatGraphicsResources->windowId); +} + +static void PrintECFields(void) +{ + u16 *ecWord; + u8 numColumns, numRows; + u8 *str; + u8 frameId; + int i, j, k; + + ecWord = GetEasyChatWordBuffer(); + numColumns = GetNumColumns(); + numRows = GetNumRows(); + frameId = GetEasyChatScreenFrameId(); + FillWindowPixelBuffer(sEasyChatGraphicsResources->windowId, PIXEL_FILL(1)); + for (i = 0; i < numRows; i++) + { + str = sEasyChatGraphicsResources->ecPrintBuffer; + str[0] = EOS; + str = StringAppend(str, sText_Clear17); + for (j = 0; j < numColumns; j++) + { + if (*ecWord != 0xFFFF) + { + str = CopyEasyChatWord(str, *ecWord); + ecWord++; + } + else + { + str = WriteColorChangeControlCode(str, 0, TEXT_COLOR_RED); + ecWord++; + for (k = 0; k < 7; k++) + { + *str++ = CHAR_EXTRA_EMOJI; + *str++ = 9; + } + + str = WriteColorChangeControlCode(str, 0, TEXT_COLOR_DARK_GREY); + } + + str = StringAppend(str, sText_Clear17); + if (frameId == 2) + { + if (j == 0 && i == 4) + break; + } + } + + *str = EOS; + EC_AddTextPrinterParameterized(sEasyChatGraphicsResources->windowId, 1, sEasyChatGraphicsResources->ecPrintBuffer, 0, i * 16, TEXT_SPEED_FF, NULL); + } + + CopyWindowToVram(sEasyChatGraphicsResources->windowId, 3); +} + +static void DrawECFrameInTilemapBuffer(u16 *tilemap) +{ + u8 frameId; + int right, bottom; + int x, y; + + frameId = GetEasyChatScreenFrameId(); + CpuFastFill(0, tilemap, BG_SCREEN_SIZE); + if (frameId == 2) + { + right = sPhraseFrameDimensions[frameId].left + sPhraseFrameDimensions[frameId].width; + bottom = sPhraseFrameDimensions[frameId].top + sPhraseFrameDimensions[frameId].height; + for (y = sPhraseFrameDimensions[frameId].top; y < bottom; y++) + { + x = sPhraseFrameDimensions[frameId].left - 1; + tilemap[y * 32 + x] = 0x1005; + x++; + for (; x < right; x++) + tilemap[y * 32 + x] = 0x1000; + + tilemap[y* 32 + x] = 0x1007; + } + } + else + { + y = sPhraseFrameDimensions[frameId].top - 1; + x = sPhraseFrameDimensions[frameId].left - 1; + right = sPhraseFrameDimensions[frameId].left + sPhraseFrameDimensions[frameId].width; + bottom = sPhraseFrameDimensions[frameId].top + sPhraseFrameDimensions[frameId].height; + tilemap[y * 32 + x] = 0x1001; + x++; + for (; x < right; x++) + tilemap[y * 32 + x] = 0x1002; + + tilemap[y * 32 + x] = 0x1003; + y++; + for (; y < bottom; y++) + { + x = sPhraseFrameDimensions[frameId].left - 1; + tilemap[y * 32 + x] = 0x1005; + x++; + for (; x < right; x++) + tilemap[y * 32 + x] = 0x1000; + + tilemap[y* 32 + x] = 0x1007; + } + + x = sPhraseFrameDimensions[frameId].left - 1; + tilemap[y * 32 + x] = 0x1009; + x++; + for (; x < right; x++) + tilemap[y * 32 + x] = 0x100A; + + tilemap[y * 32 + x] = 0x100B; + } +} + +static void PutWin2TilemapAndCopyToVram(void) +{ + PutWindowTilemap(2); + CopyBgTilemapBufferToVram(2); +} + +static void PrintECMenuById(u32 id) +{ + InitBg2Scroll(); + FillWindowPixelBuffer(2, PIXEL_FILL(1)); + switch (id) + { + case 0: + PrintECGroupsMenu(); + break; + case 1: + PrintEasyChatKeyboardText(); + break; + case 2: + PrintECWordsMenu(); + break; + } + + CopyWindowToVram(2, 2); +} + +static void PrintECGroupOrAlphaMenu(void) +{ + if (!IsEasyChatAlphaMode()) + PrintECMenuById(0); + else + PrintECMenuById(1); +} + +static void PrintECGroupsMenu(void) +{ + int i; + int x, y; + + i = 0; + y = 96; + while (1) + { + for (x = 0; x < 2; x++) + { + u8 groupId = GetSelectedGroupByIndex(i++); + if (groupId == EC_NUM_GROUPS) + { + ScheduleBg2VerticalScroll(GetECSelectGroupRowsAbove(), 0); + return; + } + + EC_AddTextPrinterParameterized(2, 1, GetEasyChatWordGroupName(groupId), x * 84 + 10, y, TEXT_SPEED_FF, NULL); + } + + y += 16; + } +} + +static void PrintEasyChatKeyboardText(void) +{ + u32 i; + + for (i = 0; i < NELEMS(sEasyChatKeyboardText); i++) + EC_AddTextPrinterParameterized(2, 1, sEasyChatKeyboardText[i], 10, 96 + i * 16, TEXT_SPEED_FF, NULL); +} + +static void PrintECWordsMenu(void) +{ + PrintECRowsWin2(0, 4); +} + +static void UpdateWin2PrintWordsScrollDown(void) +{ + u8 rowsAbove = GetECSelectWordRowsAbove() + 3; + ClearECRowsWin2(rowsAbove, 1); + PrintECRowsWin2(rowsAbove, 1); +} + +static void UpdateWin2PrintWordsScrollUp(void) +{ + u8 rowsAbove = GetECSelectWordRowsAbove(); + ClearECRowsWin2(rowsAbove, 1); + PrintECRowsWin2(rowsAbove, 1); +} + +static void UpdateWin2PrintWordsScrollPageDown(void) +{ + u8 row = GetECSelectWordRowsAbove(); + u8 maxrow = row + 4; + u8 numrowsplus1 = GetECSelectWordNumRows() + 1; + if (maxrow > numrowsplus1) + maxrow = numrowsplus1; + + if (row < maxrow) + { + u8 remrow = maxrow - row; + ClearECRowsWin2(row, remrow); + PrintECRowsWin2(row, remrow); + } +} + +static void UpdateWin2PrintWordsScrollPageUp(void) +{ + u8 row = GetECSelectWordRowsAbove(); + u8 maxrow = GetBg2ScrollRow(); + if (row < maxrow) + { + u8 remrow = maxrow - row; + ClearECRowsWin2(row, remrow); + PrintECRowsWin2(row, remrow); + } +} + +static void PrintECRowsWin2(u8 row, u8 remrow) +{ + int i, j; + u16 easyChatWord; + u8 *str; + int y; + u8 y_; + int ecWordIdx; + + ecWordIdx = row * 2; + y = (row * 16 + 96) & 0xFF; + + for (i = 0; i < remrow; i++) + { + for (j = 0; j < 2; j++) + { + // FIXME: Dumb trick needed to match + y_ = y << 18 >> 18; + easyChatWord = GetDisplayedWordByIndex(ecWordIdx++); + if (easyChatWord != 0xFFFF) + { + + CopyEasyChatWordPadded(sEasyChatGraphicsResources->ecPaddedWordBuffer, easyChatWord, 0); + + EC_AddTextPrinterParameterized(2, 1, sEasyChatGraphicsResources->ecPaddedWordBuffer, (j * 13 + 3) * 8, y_, TEXT_SPEED_FF, NULL); + } + } + y += 16; + + } + + CopyWindowToVram(2, 2); +} + +static void ClearECRowsWin2(u8 row, u8 remrow) +{ + int y; + int totalHeight; + int heightWrappedAround; + int heightToBottom; + + y = (row * 16 + 96) & 0xFF; + heightToBottom = remrow * 16; + totalHeight = y + heightToBottom; + if (totalHeight > 255) + { + heightWrappedAround = totalHeight - 256; + heightToBottom = 256 - y; + } + else + { + heightWrappedAround = 0; + } + + FillWindowPixelRect(2, PIXEL_FILL(1), 0, y, 224, heightToBottom); + if (heightWrappedAround) + FillWindowPixelRect(2, PIXEL_FILL(1), 0, 0, 224, heightWrappedAround); +} + +static void ClearWin2AndCopyToVram(void) +{ + FillWindowPixelBuffer(2, PIXEL_FILL(1)); + CopyWindowToVram(2, 2); +} + +static void StartWin2FrameAnim(int animNo) +{ + switch (animNo) + { + case 0: + sEasyChatGraphicsResources->frameAnimIdx = 0; + sEasyChatGraphicsResources->frameAnimTarget = 10; + break; + case 1: + sEasyChatGraphicsResources->frameAnimIdx = 9; + sEasyChatGraphicsResources->frameAnimTarget = 0; + break; + case 2: + sEasyChatGraphicsResources->frameAnimIdx = 11; + sEasyChatGraphicsResources->frameAnimTarget = 17; + break; + case 3: + sEasyChatGraphicsResources->frameAnimIdx = 17; + sEasyChatGraphicsResources->frameAnimTarget = 0; + break; + case 4: + sEasyChatGraphicsResources->frameAnimIdx = 17; + sEasyChatGraphicsResources->frameAnimTarget = 10; + break; + case 5: + sEasyChatGraphicsResources->frameAnimIdx = 18; + sEasyChatGraphicsResources->frameAnimTarget = 22; + break; + case 6: + sEasyChatGraphicsResources->frameAnimIdx = 22; + sEasyChatGraphicsResources->frameAnimTarget = 18; + break; + } + + sEasyChatGraphicsResources->frameAnimDelta = sEasyChatGraphicsResources->frameAnimIdx < sEasyChatGraphicsResources->frameAnimTarget ? 1 : -1; +} + +static bool8 AnimateFrameResize(void) +{ + if (sEasyChatGraphicsResources->frameAnimIdx == sEasyChatGraphicsResources->frameAnimTarget) + return FALSE; + + sEasyChatGraphicsResources->frameAnimIdx += sEasyChatGraphicsResources->frameAnimDelta; + RedrawFrameByIndex(sEasyChatGraphicsResources->frameAnimIdx); + return sEasyChatGraphicsResources->frameAnimIdx != sEasyChatGraphicsResources->frameAnimTarget; +} + +static void RedrawFrameByIndex(u8 direction) +{ + FillBgTilemapBufferRect_Palette0(1, 0, 0, 10, 30, 10); + switch (direction) + { + case 0: + break; + case 1: + RedrawFrameByRect(11, 14, 3, 2); + break; + case 2: + RedrawFrameByRect(9, 14, 7, 2); + break; + case 3: + RedrawFrameByRect(7, 14, 11, 2); + break; + case 4: + RedrawFrameByRect(5, 14, 15, 2); + break; + case 5: + RedrawFrameByRect(3, 14, 19, 2); + break; + case 6: + RedrawFrameByRect(1, 14, 23, 2); + break; + case 7: + RedrawFrameByRect(1, 13, 23, 4); + break; + case 8: + RedrawFrameByRect(1, 12, 23, 6); + break; + case 9: + RedrawFrameByRect(1, 11, 23, 8); + break; + case 10: + RedrawFrameByRect(1, 10, 23, 10); + break; + case 11: + RedrawFrameByRect(1, 10, 24, 10); + break; + case 12: + RedrawFrameByRect(1, 10, 25, 10); + break; + case 13: + RedrawFrameByRect(1, 10, 26, 10); + break; + case 14: + RedrawFrameByRect(1, 10, 27, 10); + break; + case 15: + RedrawFrameByRect(1, 10, 28, 10); + break; + case 16: + RedrawFrameByRect(1, 10, 29, 10); + break; + case 17: + RedrawFrameByRect(0, 10, 30, 10); + break; + case 18: + RedrawFrameByRect(1, 10, 23, 10); + break; + case 19: + RedrawFrameByRect(1, 11, 23, 8); + break; + case 20: + RedrawFrameByRect(1, 12, 23, 6); + break; + case 21: + RedrawFrameByRect(1, 13, 23, 4); + break; + case 22: + RedrawFrameByRect(1, 14, 23, 2); + break; + } + + CopyBgTilemapBufferToVram(1); +} + +static void RedrawFrameByRect(int left, int top, int width, int height) +{ + u16 *tilemap; + int right; + int bottom; + int x, y; + + tilemap = sEasyChatGraphicsResources->bg1TilemapBuffer; + right = left + width - 1; + bottom = top + height - 1; + x = left; + y = top; + tilemap[y * 32 + x] = 0x4001; + x++; + for (; x < right; x++) + tilemap[y * 32 + x] = 0x4002; + + tilemap[y * 32 + x] = 0x4003; + y++; + for (; y < bottom; y++) + { + tilemap[y * 32 + left] = 0x4005; + x = left + 1; + for (; x < right; x++) + tilemap[y * 32 + x] = 0x4000; + + tilemap[y * 32 + x] = 0x4007; + } + + tilemap[y * 32 + left] = 0x4009; + x = left + 1; + for (; x < right; x++) + tilemap[y * 32 + x] = 0x400A; + + tilemap[y * 32 + x] = 0x400B; + SetRegWin0Coords((left + 1) * 8, (top + 1) * 8, (width - 2) * 8, (height - 2) * 8); +} + +static void InitBg2Scroll(void) +{ + ChangeBgY(2, 0x800, 0); + sEasyChatGraphicsResources->bg2ScrollRow = 0; +} + +static void ScheduleBg2VerticalScroll(s16 direction, u8 speed) +{ + int bgY; + s16 totalDelta; + + bgY = GetBgY(2); + sEasyChatGraphicsResources->bg2ScrollRow += direction; + totalDelta = direction * 16; + bgY += totalDelta << 8; + if (speed) + { + sEasyChatGraphicsResources->tgtBgY = bgY; + sEasyChatGraphicsResources->deltaBgY = speed * 256; + if (totalDelta < 0) + sEasyChatGraphicsResources->deltaBgY = -sEasyChatGraphicsResources->deltaBgY; + } + else + { + ChangeBgY(2, bgY, 0); + } +} + +static bool8 AnimateBg2VerticalScroll(void) +{ + int bgY; + + bgY = GetBgY(2); + if (bgY == sEasyChatGraphicsResources->tgtBgY) + { + return FALSE; + } + else + { + ChangeBgY(2, sEasyChatGraphicsResources->deltaBgY, 1); + return TRUE; + } +} + +static int GetBg2ScrollRow(void) +{ + return sEasyChatGraphicsResources->bg2ScrollRow; +} + +static void SetRegWin0Coords(u8 left, u8 top, u8 width, u8 height) +{ + u16 horizontalDimensions = WIN_RANGE(left, left + width); + u16 verticalDimensions = WIN_RANGE(top, top + height); + SetGpuReg(REG_OFFSET_WIN0H, horizontalDimensions); + SetGpuReg(REG_OFFSET_WIN0V, verticalDimensions); +} + +static void LoadSpriteGfx(void) +{ + u32 i; + + LoadSpriteSheets(sEasyChatSpriteSheets); + LoadSpritePalettes(sEasyChatSpritePalettes); + for (i = 0; i < NELEMS(sEasyChatCompressedSpriteSheets); i++) + LoadCompressedSpriteSheet(&sEasyChatCompressedSpriteSheets[i]); +} + +static void CreateSelectDestFieldCursorSprite(void) +{ + u8 frameId = GetEasyChatScreenFrameId(); + s16 x = sPhraseFrameDimensions[frameId].left * 8 + 13; + s16 y = (sPhraseFrameDimensions[frameId].top + 1) * 8 + 1; + u8 spriteId = CreateSprite(&sSpriteTemplate_RightTriangleCursor, x, y, 2); + sEasyChatGraphicsResources->selectDestFieldCursorSprite = &gSprites[spriteId]; + gSprites[spriteId].data[1] = 1; +} + +static void SpriteCB_BounceCursor(struct Sprite * sprite) +{ + if (sprite->data[1]) + { + if (++sprite->data[0] > 2) + { + sprite->data[0] = 0; + if (++sprite->pos2.x > 0) + sprite->pos2.x = -6; + } + } +} + +static void SetSelectDestFieldCursorSpritePosAndResetAnim(u8 x, u8 y) +{ + sEasyChatGraphicsResources->selectDestFieldCursorSprite->pos1.x = x; + sEasyChatGraphicsResources->selectDestFieldCursorSprite->pos1.y = y; + sEasyChatGraphicsResources->selectDestFieldCursorSprite->pos2.x = 0; + sEasyChatGraphicsResources->selectDestFieldCursorSprite->data[0] = 0; +} + +static void FreezeSelectDestFieldCursorSprite(void) +{ + sEasyChatGraphicsResources->selectDestFieldCursorSprite->data[0] = 0; + sEasyChatGraphicsResources->selectDestFieldCursorSprite->data[1] = 0; + sEasyChatGraphicsResources->selectDestFieldCursorSprite->pos2.x = 0; +} + +static void UnfreezeSelectDestFieldCursorSprite(void) +{ + sEasyChatGraphicsResources->selectDestFieldCursorSprite->data[1] = 1; +} + +static void CreateRedRectangularCursorSpritePair(void) +{ + u8 spriteId = CreateSprite(&sSpriteTemplate_RedRectangularCursor, 0, 0, 3); + sEasyChatGraphicsResources->rectCursorSpriteRight = &gSprites[spriteId]; + sEasyChatGraphicsResources->rectCursorSpriteRight->pos2.x = 32; + + spriteId = CreateSprite(&sSpriteTemplate_RedRectangularCursor, 0, 0, 3); + sEasyChatGraphicsResources->rectCursorSpriteLeft = &gSprites[spriteId]; + sEasyChatGraphicsResources->rectCursorSpriteLeft->pos2.x = -32; + + sEasyChatGraphicsResources->rectCursorSpriteRight->hFlip = TRUE; + EC_MoveCursor(); +} + +static void DestroyRedRectangularCursor(void) +{ + DestroySprite(sEasyChatGraphicsResources->rectCursorSpriteRight); + sEasyChatGraphicsResources->rectCursorSpriteRight = NULL; + DestroySprite(sEasyChatGraphicsResources->rectCursorSpriteLeft); + sEasyChatGraphicsResources->rectCursorSpriteLeft = NULL; +} + +static void EC_MoveCursor(void) +{ + u8 x; + u8 y; + + if (sEasyChatGraphicsResources->rectCursorSpriteRight && sEasyChatGraphicsResources->rectCursorSpriteLeft) + { + GetECSelectGroupCursorCoords(&x, &y); + if (!IsEasyChatAlphaMode()) + MoveCursor_Group(x, y); + else + MoveCursor_Alpha(x, y); + } +} + +static void MoveCursor_Group(s8 x, s8 y) +{ + if (x != -1) + { + StartSpriteAnim(sEasyChatGraphicsResources->rectCursorSpriteRight, 0); + sEasyChatGraphicsResources->rectCursorSpriteRight->pos1.x = x * 84 + 58; + sEasyChatGraphicsResources->rectCursorSpriteRight->pos1.y = y * 16 + 96; + + StartSpriteAnim(sEasyChatGraphicsResources->rectCursorSpriteLeft, 0); + sEasyChatGraphicsResources->rectCursorSpriteLeft->pos1.x = x * 84 + 58; + sEasyChatGraphicsResources->rectCursorSpriteLeft->pos1.y = y * 16 + 96; + } + else + { + StartSpriteAnim(sEasyChatGraphicsResources->rectCursorSpriteRight, 1); + sEasyChatGraphicsResources->rectCursorSpriteRight->pos1.x = 216; + sEasyChatGraphicsResources->rectCursorSpriteRight->pos1.y = y * 16 + 112; + + StartSpriteAnim(sEasyChatGraphicsResources->rectCursorSpriteLeft, 1); + sEasyChatGraphicsResources->rectCursorSpriteLeft->pos1.x = 216; + sEasyChatGraphicsResources->rectCursorSpriteLeft->pos1.y = y * 16 + 112; + } +} + +static void MoveCursor_Alpha(s8 cursorX, s8 cursorY) +{ + int anim; + int x, y; + + if (cursorX != -1) + { + y = cursorY * 16 + 96; + x = 32; + if (cursorX == 6 && cursorY == 0) + { + x = 157; + anim = 2; + } + else + { + x += sECDisplay_AlphaModeXCoords[cursorX < NELEMS(sECDisplay_AlphaModeXCoords) ? cursorX : 0]; + anim = 3; + } + + StartSpriteAnim(sEasyChatGraphicsResources->rectCursorSpriteRight, anim); + sEasyChatGraphicsResources->rectCursorSpriteRight->pos1.x = x; + sEasyChatGraphicsResources->rectCursorSpriteRight->pos1.y = y; + + StartSpriteAnim(sEasyChatGraphicsResources->rectCursorSpriteLeft, anim); + sEasyChatGraphicsResources->rectCursorSpriteLeft->pos1.x = x; + sEasyChatGraphicsResources->rectCursorSpriteLeft->pos1.y = y; + } + else + { + StartSpriteAnim(sEasyChatGraphicsResources->rectCursorSpriteRight, 1); + sEasyChatGraphicsResources->rectCursorSpriteRight->pos1.x = 216; + sEasyChatGraphicsResources->rectCursorSpriteRight->pos1.y = cursorY * 16 + 112; + + StartSpriteAnim(sEasyChatGraphicsResources->rectCursorSpriteLeft, 1); + sEasyChatGraphicsResources->rectCursorSpriteLeft->pos1.x = 216; + sEasyChatGraphicsResources->rectCursorSpriteLeft->pos1.y = cursorY * 16 + 112; + } +} + +static void CreateSelectWordCursorSprite(void) +{ + u8 spriteId = CreateSprite(&sSpriteTemplate_RightTriangleCursor, 0, 0, 4); + sEasyChatGraphicsResources->selectWordCursorSprite = &gSprites[spriteId]; + sEasyChatGraphicsResources->selectWordCursorSprite->callback = SpriteCB_SelectWordCursorSprite; + sEasyChatGraphicsResources->selectWordCursorSprite->oam.priority = 2; + SetSelectWordCursorSpritePos(); +} + +static void SpriteCB_SelectWordCursorSprite(struct Sprite * sprite) +{ + if (++sprite->data[0] > 2) + { + sprite->data[0] = 0; + if (++sprite->pos2.x > 0) + sprite->pos2.x = -6; + } +} + +static void SetSelectWordCursorSpritePos(void) +{ + s8 cursorX, cursorY; + u8 x, y; + + GetECSelectWordCursorCoords(&cursorX, &cursorY); + x = cursorX * 13 + 3; + y = cursorY * 2 + 11; + SetSelectWordCursorSpritePosExplicit(x, y); +} + +static void SetSelectWordCursorSpritePosExplicit(u8 x, u8 y) +{ + if (sEasyChatGraphicsResources->selectWordCursorSprite) + { + sEasyChatGraphicsResources->selectWordCursorSprite->pos1.x = x * 8 + 4; + sEasyChatGraphicsResources->selectWordCursorSprite->pos1.y = (y + 1) * 8 + 1; + sEasyChatGraphicsResources->selectWordCursorSprite->pos2.x = 0; + sEasyChatGraphicsResources->selectWordCursorSprite->data[0] = 0; + } +} + +static void DestroySelectWordCursorSprite(void) +{ + if (sEasyChatGraphicsResources->selectWordCursorSprite) + { + DestroySprite(sEasyChatGraphicsResources->selectWordCursorSprite); + sEasyChatGraphicsResources->selectWordCursorSprite = NULL; + } +} + +static void CreateSelectGroupHelpSprite(void) +{ + u8 spriteId = CreateSprite(&sSpriteTemplate_SelectGroupHelp, 208, 128, 6); + sEasyChatGraphicsResources->selectGroupHelpSprite = &gSprites[spriteId]; + sEasyChatGraphicsResources->selectGroupHelpSprite->pos2.x = -64; + + spriteId = CreateSprite(&sSpriteTemplate_EasyChatModeIcons, 208, 80, 5); + sEasyChatGraphicsResources->modeIconsSprite = &gSprites[spriteId]; + sEasyChatGraphicsResources->modeIconState = 0; +} + +static bool8 AnimateSeletGroupModeAndHelpSpriteEnter(void) +{ + switch (sEasyChatGraphicsResources->modeIconState) + { + default: + return FALSE; + case 0: + sEasyChatGraphicsResources->selectGroupHelpSprite->pos2.x += 8; + if (sEasyChatGraphicsResources->selectGroupHelpSprite->pos2.x >= 0) + { + sEasyChatGraphicsResources->selectGroupHelpSprite->pos2.x = 0; + if (!IsEasyChatAlphaMode()) + StartSpriteAnim(sEasyChatGraphicsResources->modeIconsSprite, 1); + else + StartSpriteAnim(sEasyChatGraphicsResources->modeIconsSprite, 2); + + sEasyChatGraphicsResources->modeIconState++; + } + break; + case 1: + if (sEasyChatGraphicsResources->modeIconsSprite->animEnded) + { + sEasyChatGraphicsResources->modeIconState = 2; + return FALSE; + } + } + + return TRUE; +} + +static void StartModeIconHidingAnimation(void) +{ + sEasyChatGraphicsResources->modeIconState = 0; + StartSpriteAnim(sEasyChatGraphicsResources->modeIconsSprite, 3); +} + +static bool8 RunModeIconHidingAnimation(void) +{ + switch (sEasyChatGraphicsResources->modeIconState) + { + default: + return FALSE; + case 0: + if (sEasyChatGraphicsResources->modeIconsSprite->animEnded) + sEasyChatGraphicsResources->modeIconState = 1; + break; + case 1: + sEasyChatGraphicsResources->selectGroupHelpSprite->pos2.x -= 8; + if (sEasyChatGraphicsResources->selectGroupHelpSprite->pos2.x <= -64) + { + DestroySprite(sEasyChatGraphicsResources->modeIconsSprite); + DestroySprite(sEasyChatGraphicsResources->selectGroupHelpSprite); + sEasyChatGraphicsResources->modeIconsSprite = NULL; + sEasyChatGraphicsResources->selectGroupHelpSprite = NULL; + sEasyChatGraphicsResources->modeIconState++; + return FALSE; + } + } + + return TRUE; +} + +static void ShrinkModeIconsSprite(void) +{ + StartSpriteAnim(sEasyChatGraphicsResources->modeIconsSprite, 4); +} + +static void ShowModeIconsSprite(void) +{ + if (!IsEasyChatAlphaMode()) + StartSpriteAnim(sEasyChatGraphicsResources->modeIconsSprite, 1); + else + StartSpriteAnim(sEasyChatGraphicsResources->modeIconsSprite, 2); +} + +static bool8 ModeIconsSpriteAnimIsEnded(void) +{ + return !sEasyChatGraphicsResources->modeIconsSprite->animEnded; +} + +static void CreateVerticalScrollArrowSprites(void) +{ + u8 spriteId = CreateSprite(&sSpriteTemplate_UpTriangleCursor, 96, 80, 0); + if (spriteId != MAX_SPRITES) + sEasyChatGraphicsResources->upTriangleCursorSprite = &gSprites[spriteId]; + + spriteId = CreateSprite(&sSpriteTemplate_UpTriangleCursor, 96, 156, 0); + if (spriteId != MAX_SPRITES) + { + sEasyChatGraphicsResources->downTriangleCursorSprite = &gSprites[spriteId]; + sEasyChatGraphicsResources->downTriangleCursorSprite->vFlip = TRUE; + } + + HideVerticalScrollArrowSprites(); +} + +static void UpdateVerticalScrollArrowVisibility(void) +{ + sEasyChatGraphicsResources->upTriangleCursorSprite->invisible = !ShouldDrawECUpArrow(); + sEasyChatGraphicsResources->downTriangleCursorSprite->invisible = !ShouldDrawECDownArrow(); +} + +static void HideVerticalScrollArrowSprites(void) +{ + sEasyChatGraphicsResources->upTriangleCursorSprite->invisible = TRUE; + sEasyChatGraphicsResources->downTriangleCursorSprite->invisible = TRUE; +} + +static void UpdateVerticalScrollArrowSpriteXPos(int direction) +{ + if (!direction) + { + // Group select + sEasyChatGraphicsResources->upTriangleCursorSprite->pos1.x = 96; + sEasyChatGraphicsResources->downTriangleCursorSprite->pos1.x = 96; + } + else + { + // Word select + sEasyChatGraphicsResources->upTriangleCursorSprite->pos1.x = 120; + sEasyChatGraphicsResources->downTriangleCursorSprite->pos1.x = 120; + } +} + +static void CreateStartSelectButtonsSprites(void) +{ + u8 spriteId = CreateSprite(&sSpriteTemplate_StartSelectButtons, 220, 84, 1); + if (spriteId != MAX_SPRITES) + sEasyChatGraphicsResources->startPgUpButtonSprite = &gSprites[spriteId]; + + spriteId = CreateSprite(&sSpriteTemplate_StartSelectButtons, 220, 156, 1); + if (spriteId != MAX_SPRITES) + { + sEasyChatGraphicsResources->selectPgDnButtonSprite = &gSprites[spriteId]; + StartSpriteAnim(sEasyChatGraphicsResources->selectPgDnButtonSprite, 1); + } + + HideStartSelectButtonSprites(); +} + +static void UpdateStartSelectButtonSpriteVisibility(void) +{ + sEasyChatGraphicsResources->startPgUpButtonSprite->invisible = !ShouldDrawECUpArrow(); + sEasyChatGraphicsResources->selectPgDnButtonSprite->invisible = !ShouldDrawECDownArrow(); +} + +static void HideStartSelectButtonSprites(void) +{ + sEasyChatGraphicsResources->startPgUpButtonSprite->invisible = TRUE; + sEasyChatGraphicsResources->selectPgDnButtonSprite->invisible = TRUE; +} + +static void CreateFooterWindow(void) +{ + u16 windowId; + struct WindowTemplate template; + template.bg = 3; + template.tilemapLeft = 4; + template.tilemapTop = 11; + template.width = 24; + template.height = 2; + template.paletteNum = 11; + template.baseBlock = 0x030; + windowId = AddWindow(&template); + FillWindowPixelBuffer(windowId, PIXEL_FILL(1)); + EC_AddTextPrinterParameterized(windowId, 1, gUnknown_841EE2B, 0, 0, 0, NULL); + PutWindowTilemap(windowId); +} |