#include "global.h" #include "naming_screen.h" #include "data2.h" #include "graphics.h" #include "field_effect.h" #include "event_object_movement.h" #include "field_player_avatar.h" #include "main.h" #include "menu.h" #include "palette.h" #include "pokemon_icon.h" #include "constants/songs.h" #include "sound.h" #include "sprite.h" #include "string_util.h" #include "strings2.h" #include "task.h" #include "text.h" #include "trig.h" #include "util.h" #include "ewram.h" #ifdef ENGLISH #define COLUMN_COUNT 9 #elif GERMAN #define COLUMN_COUNT 10 #endif const u8 gSpriteImage_83CE094[] = INCBIN_U8("graphics/naming_screen/pc_icon/0.4bpp"); const u8 gSpriteImage_83CE154[] = INCBIN_U8("graphics/naming_screen/pc_icon/1.4bpp"); struct NamingScreenData *const namingScreenDataPtr = &namingScreenData; extern const struct SubspriteTable gSubspriteTables_83CE558[]; extern const struct SubspriteTable gSubspriteTables_83CE560[]; extern const struct SubspriteTable gSubspriteTables_83CE578[]; extern const struct SubspriteTable gSubspriteTables_83CE580[]; extern const struct SpriteTemplate gSpriteTemplate_83CE5C8; extern const struct SpriteTemplate gSpriteTemplate_83CE5E0; extern const struct SpriteTemplate gSpriteTemplate_83CE5F8; extern const struct SpriteTemplate gSpriteTemplate_83CE610; extern const struct SpriteTemplate gSpriteTemplate_83CE628; extern const struct SpriteTemplate gSpriteTemplate_83CE640; extern const struct SpriteTemplate gSpriteTemplate_83CE658; extern const struct SpriteTemplate gSpriteTemplate_83CE670; extern const struct SpriteTemplate gSpriteTemplate_83CE688; extern const struct SpriteSheet gUnknown_083CE6A0[]; extern const struct SpritePalette gUnknown_083CE708[]; extern const u8 gNamingScreenMenu_Gfx[]; extern const u16 gUnknown_083CE748[]; extern const u16 gUnknown_083CEBF8[]; extern const u16 gUnknown_083CF0A8[]; extern const u16 gUnknown_08E86258[]; static void C2_NamingScreen(void); static void sub_80B5AA0(void); static void StoreNamingScreenParameters(u8, u8 *, u16, u16, u32, MainCallback); static void NamingScreen_TurnOffScreen(void); static void NamingScreen_Init(void); static void NamingScreen_ClearVram(void); static void NamingScreen_ClearOam(void); static void NamingScreen_SetUpVideoRegs(void); static void NamingScreen_SetUpWindow(void); static void NamingScreen_ResetObjects(void); static void sub_80B5DFC(void); static void sub_80B5E20(void); static void sub_80B5E3C(void); static void NamingScreen_InitDisplayMode(void); static void Task_DoNothing(u8); static void sub_80B7558(void); static void sub_80B753C(void); static void sub_80B7680(void); static void sub_80B75C4(void); static void sub_80B7794(void); static void sub_80B78A8(void); static void sub_80B7960(void); static void CursorInit(void); static void sub_80B6A80(void); static void sub_80B6CA8(void); static void sub_80B6D04(void); static void sub_80B6E44(void); static void InputInit(void); static void sub_80B6438(void); static void sub_80B5E50(void); static void Task_NamingScreenMain(u8); static void SetInputState(u8); static void sub_80B68D8(u8); static bool8 HandleKeyboardEvent(void); static bool8 IsCursorAnimFinished(void); static void MoveCursorToOKButton(void); static void sub_80B6B14(void); static void StartPageSwapAnim(void); static void sub_80B6888(u8); static void sub_80B6460(u8, u8, u8); static bool8 IsPageSwapAnimNotInProgress(void); static void sub_80B7614(void); static void GetCursorPos(s16 *, s16 *); static void SetCursorPos(s16, s16); static void sub_80B77F8(void); static void sub_80B74B0(void); static void DisplaySentToPCMessage(void); static u8 GetKeyRoleAtCursorPos(void); static u8 sub_80B61C8(void); static void DeleteTextCharacter(void); static void sub_80B7090(void); static u8 GetInputEvent(void); static bool8 sub_80B7004(void); static void sub_80B6914(void); static void Task_HandlePageSwapAnim(u8); static void sub_80B6C48(u8, struct Sprite *, struct Sprite *); static u8 GetTextCaretPosition(void); static u8 GetCharAtKeyboardPos(s16, s16); static bool8 sub_80B7104(void); static bool8 sub_80B713C(void); static void AddTextCharacter(u8); static bool8 sub_80B7198(u8); static bool8 sub_80B7264(u8); static void sub_80B7370(u8, u8); static void sub_80B73CC(u8, u8); static bool8 sub_80B71E4(u8); static void sub_80B7474(u8, u8); static void sub_80B72A4(u8, u8); static bool8 sub_80B720C(u8); static void sub_80B7568(void); static void sub_80B75B0(void); static void sub_80B7698(u16 *, const u16 *); static void sub_80B76E0(); static void nullsub_20(u8, u8); static void PrintKeyboardCharacters(u8); void DoNamingScreen(u8 templateNum, u8 *destBuffer, u16 speciesOrPlayerGender, u16 monGender, u32 monPersonality, MainCallback returnCallback) { StoreNamingScreenParameters(templateNum, destBuffer, speciesOrPlayerGender, monGender, monPersonality, returnCallback); SetMainCallback2(C2_NamingScreen); } static void C2_NamingScreen(void) { switch (gMain.state) { case 0: NamingScreen_TurnOffScreen(); NamingScreen_Init(); gMain.state++; break; case 1: NamingScreen_ClearVram(); gMain.state++; break; case 2: NamingScreen_ClearOam(); gMain.state++; break; case 3: NamingScreen_SetUpVideoRegs(); gMain.state++; break; case 4: NamingScreen_SetUpWindow(); gMain.state++; break; case 5: NamingScreen_ResetObjects(); gMain.state++; break; case 6: sub_80B5DFC(); gMain.state++; break; case 7: sub_80B5E20(); sub_80B5E3C(); NamingScreen_InitDisplayMode(); SetMainCallback2(sub_80B5AA0); break; } } static void sub_80B5AA0(void) { RunTasks(); AnimateSprites(); BuildOamBuffer(); UpdatePaletteFade(); } static void VBlankCB_NamingScreen(void) { LoadOam(); ProcessSpriteCopyRequests(); TransferPlttBuffer(); REG_BG1VOFS = namingScreenDataPtr->bg1vOffset; REG_BG2VOFS = namingScreenDataPtr->bg2vOffset; REG_BG1CNT &= 0xFFFC; REG_BG1CNT |= namingScreenDataPtr->bg1Priority; REG_BG2CNT &= 0xFFFC; REG_BG2CNT |= namingScreenDataPtr->bg2Priority; } static void StoreNamingScreenParameters(u8 templateNum, u8 *destBuffer, u16 speciesOrPlayerGender, u16 monGender, u32 monPersonality, MainCallback returnCallback) { struct Task *task; //Create a task that does nothing, and use it as a temporary space to store parameters task = &gTasks[CreateTask(Task_DoNothing, 0xFF)]; task->data[0] = templateNum; task->data[1] = speciesOrPlayerGender; task->data[2] = monGender; task->data[3] = monPersonality >> 16; task->data[4] = monPersonality; StoreWordInTwoHalfwords(&task->data[5], (u32)destBuffer); StoreWordInTwoHalfwords(&task->data[7], (u32)returnCallback); } static void GetNamingScreenParameters(void) { u8 taskId; struct Task *task; taskId = FindTaskIdByFunc(Task_DoNothing); task = &gTasks[taskId]; namingScreenDataPtr->templateNum = task->data[0]; namingScreenDataPtr->speciesOrPlayerGender = task->data[1]; namingScreenDataPtr->monGender = task->data[2]; namingScreenDataPtr->monPersonality = (task->data[3] << 16) | (u16)task->data[4]; LoadWordFromTwoHalfwords(&task->data[5], (u32 *)&namingScreenDataPtr->destBuffer); LoadWordFromTwoHalfwords(&task->data[7], (u32 *)&namingScreenDataPtr->returnCallback); DestroyTask(taskId); } static void Task_DoNothing(u8 taskId) { } static void NamingScreen_TurnOffScreen(void) { SetVBlankCallback(NULL); SetHBlankCallback(NULL); REG_DISPCNT = 0; } static void NamingScreen_InitDisplayMode(void) { u16 savedIme; SetVBlankCallback(VBlankCB_NamingScreen); savedIme = REG_IME; REG_IME = 0; REG_IE |= INTR_FLAG_VBLANK; REG_IME = savedIme; REG_DISPSTAT |= DISPSTAT_VBLANK_INTR; REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG_ALL_ON | DISPCNT_OBJ_ON; } static void NamingScreen_ClearVram(void) { DmaFill16Large(3, 0, (void *)VRAM, 0x10000, 0x1000); } static void NamingScreen_ClearOam(void) { DmaClear16(3, (void *)OAM, 0x400); } static void NamingScreen_SetUpVideoRegs(void) { REG_BG0CNT = 0; REG_BG1CNT = 0; REG_BG2CNT = 0; REG_BG3CNT = 0; REG_BG0HOFS = 0; REG_BG0VOFS = 0; REG_BG1HOFS = 0; REG_BG1VOFS = 0; REG_BG2HOFS = 0; REG_BG2VOFS = 0; REG_BG3HOFS = 0; REG_BG3VOFS = 0; REG_BG0CNT = BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(31) | BGCNT_16COLOR | BGCNT_TXT256x256; REG_BG1CNT = BGCNT_PRIORITY(1) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(28) | BGCNT_16COLOR | BGCNT_TXT256x256; REG_BG2CNT = BGCNT_PRIORITY(2) | BGCNT_CHARBASE(2) | BGCNT_SCREENBASE(29) | BGCNT_16COLOR | BGCNT_TXT256x256; REG_BG3CNT = BGCNT_PRIORITY(3) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(30) | BGCNT_16COLOR | BGCNT_TXT256x256; REG_BLDCNT = 0x640; REG_BLDALPHA = 0x80C; } static const struct NamingScreenTemplate *const sNamingScreenTemplates[]; //forward declaration static void NamingScreen_Init(void) { GetNamingScreenParameters(); namingScreenDataPtr->state = 0; namingScreenDataPtr->bg1vOffset = 0; namingScreenDataPtr->bg2vOffset = 0; namingScreenDataPtr->bg1Priority = BGCNT_PRIORITY(1); namingScreenDataPtr->bg2Priority = BGCNT_PRIORITY(2); namingScreenDataPtr->bgToReveal = 0; namingScreenDataPtr->bgToHide = 1; namingScreenDataPtr->template = sNamingScreenTemplates[namingScreenDataPtr->templateNum]; namingScreenDataPtr->currentPage = namingScreenDataPtr->template->initialPage; namingScreenDataPtr->nameLeftOffset = 14 - namingScreenDataPtr->template->maxChars / 2; namingScreenDataPtr->keyRepeatStartDelayCopy = gKeyRepeatStartDelay; memset(namingScreenDataPtr->textBuffer, 0xFF, sizeof(namingScreenDataPtr->textBuffer)); if (namingScreenDataPtr->template->copyExistingString) StringCopy(namingScreenDataPtr->textBuffer, namingScreenDataPtr->destBuffer); gKeyRepeatStartDelay = 16; } static void NamingScreen_SetUpWindow(void) { Text_LoadWindowTemplate(&gWindowTemplate_81E6E88); InitMenuWindow(&gWindowTemplate_81E6E88); } static void NamingScreen_ResetObjects(void) { ResetPaletteFade(); ResetSpriteData(); FreeAllSpritePalettes(); ResetTasks(); } static void sub_80B5DFC(void) { sub_80B7558(); sub_80B753C(); sub_80B7680(); sub_80B75C4(); sub_80B7794(); sub_80B78A8(); sub_80B7960(); } static void sub_80B5E20(void) { CursorInit(); sub_80B6A80(); sub_80B6CA8(); sub_80B6D04(); sub_80B6E44(); } static void sub_80B5E3C(void) { InputInit(); sub_80B6438(); sub_80B5E50(); } //-------------------------------------------------- // Naming screen main //-------------------------------------------------- static bool8 MainState_BeginFadeIn(struct Task *); static bool8 MainState_WaitFadeIn(struct Task *); static bool8 MainState_HandleInput(struct Task *); static bool8 MainState_MoveToOKButton(struct Task *); static bool8 MainState_StartPageSwap(struct Task *); static bool8 MainState_WaitPageSwap(struct Task *); static bool8 MainState_6(struct Task *); static bool8 MainState_UpdateSentToPCMessage(struct Task *); static bool8 MainState_BeginFadeInOut(struct Task *); static bool8 MainState_WaitFadeOutAndExit(struct Task *); static bool8 (*const sMainStateFuncs[])(struct Task *) = { MainState_BeginFadeIn, MainState_WaitFadeIn, MainState_HandleInput, MainState_MoveToOKButton, MainState_StartPageSwap, MainState_WaitPageSwap, MainState_6, MainState_UpdateSentToPCMessage, MainState_BeginFadeInOut, MainState_WaitFadeOutAndExit, }; static void sub_80B5E50(void) { u8 taskId; taskId = CreateTask(Task_NamingScreenMain, 2); Task_NamingScreenMain(taskId); } static void Task_NamingScreenMain(u8 taskId) { while (sMainStateFuncs[namingScreenDataPtr->state](&gTasks[taskId]) != 0) ; } static bool8 MainState_BeginFadeIn(struct Task *task) { BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB(0, 0, 0)); namingScreenDataPtr->state++; return 0; } static bool8 MainState_WaitFadeIn(struct Task *task) { if (!gPaletteFade.active) { SetInputState(INPUT_STATE_ENABLED); sub_80B68D8(1); namingScreenDataPtr->state++; } return FALSE; } static bool8 MainState_HandleInput(struct Task *task) { return HandleKeyboardEvent(); } static bool8 MainState_MoveToOKButton(struct Task *task) { if (IsCursorAnimFinished()) { SetInputState(INPUT_STATE_ENABLED); MoveCursorToOKButton(); namingScreenDataPtr->state = MAIN_STATE_HANDLE_INPUT; } return FALSE; } static bool8 MainState_StartPageSwap(struct Task *task) { SetInputState(INPUT_STATE_DISABLED); sub_80B6B14(); StartPageSwapAnim(); sub_80B6888(1); sub_80B6460(0, 0, 1); PlaySE(SE_WIN_OPEN); namingScreenDataPtr->state = MAIN_STATE_WAIT_PAGE_SWAP; return FALSE; } static bool8 MainState_WaitPageSwap(struct Task *task) { s16 cursorX; s16 cursorY; if (IsPageSwapAnimNotInProgress()) { namingScreenDataPtr->state = MAIN_STATE_HANDLE_INPUT; namingScreenDataPtr->currentPage++; namingScreenDataPtr->currentPage %= 3; sub_80B7614(); sub_80B77F8(); SetInputState(INPUT_STATE_ENABLED); GetCursorPos(&cursorX, &cursorY); #if ENGLISH if (namingScreenDataPtr->currentPage == PAGE_OTHERS && (cursorX == 6 || cursorX == 7)) cursorX = 5; #elif GERMAN if (namingScreenDataPtr->currentPage == PAGE_OTHERS && (cursorX == 7 || cursorX == 8)) cursorX = 6; #endif SetCursorPos(cursorX, cursorY); sub_80B6888(0); } return FALSE; } static bool8 MainState_6(struct Task *task) { sub_80B74B0(); SetInputState(INPUT_STATE_DISABLED); sub_80B68D8(0); sub_80B6460(3, 0, 1); gKeyRepeatStartDelay = namingScreenDataPtr->keyRepeatStartDelayCopy; if (namingScreenDataPtr->templateNum == NAMING_SCREEN_TEMPLATE_MON_NAME && CalculatePlayerPartyCount() >= 6) { DisplaySentToPCMessage(); namingScreenDataPtr->state = MAIN_STATE_UPDATE_SENT_TO_PC_MESSAGE; return FALSE; } else { namingScreenDataPtr->state = MAIN_STATE_BEGIN_FADE_OUT; return TRUE; //Exit the naming screen } } static bool8 MainState_UpdateSentToPCMessage(struct Task *task) { if (Menu_UpdateWindowText()) namingScreenDataPtr->state++; return FALSE; } static bool8 MainState_BeginFadeInOut(struct Task *task) { BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); namingScreenDataPtr->state++; return FALSE; } static bool8 MainState_WaitFadeOutAndExit(struct Task *task) { if (!gPaletteFade.active) SetMainCallback2(namingScreenDataPtr->returnCallback); return FALSE; } //-------------------------------------------------- // Keyboard handling //-------------------------------------------------- enum { KEY_ROLE_CHAR, KEY_ROLE_PAGE, KEY_ROLE_BACKSPACE, KEY_ROLE_OK, }; static bool8 KeyboardKeyHandler_Character(u8); static bool8 KeyboardKeyHandler_Page(u8); static bool8 KeyboardKeyHandler_Backspace(u8); static bool8 KeyboardKeyHandler_OK(u8); static bool8 (*const sKeyboardKeyHandlers[])(u8) = { KeyboardKeyHandler_Character, KeyboardKeyHandler_Page, KeyboardKeyHandler_Backspace, KeyboardKeyHandler_OK, }; static bool8 HandleKeyboardEvent(void) { u8 event = GetInputEvent(); u8 keyRole = GetKeyRoleAtCursorPos(); if (event == KBEVENT_PRESSED_SELECT) return sub_80B61C8(); else if (event == KBEVENT_PRESSED_B) { DeleteTextCharacter(); return FALSE; } else if (event == 7) { sub_80B7090(); return FALSE; } return sKeyboardKeyHandlers[keyRole](event); } static bool8 KeyboardKeyHandler_Character(u8 event) { sub_80B6460(3, 0, 0); if (event == KBEVENT_PRESSED_A) { u8 var = sub_80B7004(); sub_80B6914(); if (var) { SetInputState(INPUT_STATE_DISABLED); namingScreenDataPtr->state = MAIN_STATE_MOVE_TO_OK_BUTTON; } } return FALSE; } static bool8 KeyboardKeyHandler_Page(u8 event) { sub_80B6460(0, 1, 0); if (event == KBEVENT_PRESSED_A) return sub_80B61C8(); else return FALSE; } static bool8 KeyboardKeyHandler_Backspace(u8 event) { sub_80B6460(1, 1, 0); if (event == KBEVENT_PRESSED_A) DeleteTextCharacter(); return FALSE; } static bool8 KeyboardKeyHandler_OK(u8 event) { sub_80B6460(2, 1, 0); if (event == KBEVENT_PRESSED_A) { PlaySE(SE_SELECT); namingScreenDataPtr->state = MAIN_STATE_6; return TRUE; } else return FALSE; } static bool8 sub_80B61C8(void) { namingScreenDataPtr->state = MAIN_STATE_START_PAGE_SWAP; return TRUE; } //-------------------------------------------------- // Input handling //-------------------------------------------------- enum { FNKEY_CASE, FNKEY_BACK, FNKEY_OK, }; #define tState data[0] #define tKeyboardEvent data[1] #define tKbFunctionKey data[2] static void InputState_Disabled(struct Task *); static void InputState_Enabled(struct Task *); static void (*const sInputStateFuncs[])(struct Task *) = { InputState_Disabled, InputState_Enabled, }; static void Task_HandleInput(u8); static void HandleDpadMovement(struct Task *); static void InputInit(void) { CreateTask(Task_HandleInput, 1); } static u8 GetInputEvent(void) { u8 taskId = FindTaskIdByFunc(Task_HandleInput); return gTasks[taskId].tKeyboardEvent; } static void SetInputState(u8 state) { u8 taskId = FindTaskIdByFunc(Task_HandleInput); gTasks[taskId].tState = state; } static void Task_HandleInput(u8 taskId) { sInputStateFuncs[gTasks[taskId].tState](&gTasks[taskId]); } static void InputState_Disabled(struct Task *task) { task->tKeyboardEvent = 0; } static void InputState_Enabled(struct Task *task) { task->tKeyboardEvent = 0; if (gMain.newKeys & A_BUTTON) { task->tKeyboardEvent = KBEVENT_PRESSED_A; return; } if (gMain.newKeys & B_BUTTON) { task->tKeyboardEvent = KBEVENT_PRESSED_B; return; } if (gMain.newKeys & SELECT_BUTTON) { task->tKeyboardEvent = KBEVENT_PRESSED_SELECT; return; } if (gMain.newKeys & START_BUTTON) { task->tKeyboardEvent = KBEVENT_PRESSED_START; MoveCursorToOKButton(); return; } HandleDpadMovement(task); } static const s16 sDpadDeltaX[] = { 0, //none 0, //up 0, //down -1, //left 1 //right }; static const s16 sDpadDeltaY[] = { 0, //none -1, //up 1, //down 0, //left 0 //right }; static const s16 s4RowTo3RowTableY[] = {0, 1, 1, 2}; static const s16 gUnknown_083CE274[] = {0, 0, 3, 0}; static void HandleDpadMovement(struct Task *task) { s16 cursorX; s16 cursorY; u16 dpadDir; s16 prevCursorX; GetCursorPos(&cursorX, &cursorY); dpadDir = 0; if (gMain.newAndRepeatedKeys & DPAD_UP) dpadDir = 1; if (gMain.newAndRepeatedKeys & DPAD_DOWN) dpadDir = 2; if (gMain.newAndRepeatedKeys & DPAD_LEFT) dpadDir = 3; if (gMain.newAndRepeatedKeys & DPAD_RIGHT) dpadDir = 4; //Get new cursor position prevCursorX = cursorX; cursorX += sDpadDeltaX[dpadDir]; cursorY += sDpadDeltaY[dpadDir]; //Wrap cursor position in the X direction if (cursorX < 0) cursorX = COLUMN_COUNT - 1; if (cursorX > COLUMN_COUNT - 1) cursorX = 0; //Handle cursor movement in X direction if (sDpadDeltaX[dpadDir] != 0) { //The "others" page only has 5 columns #if ENGLISH if (namingScreenDataPtr->currentPage == PAGE_OTHERS && (cursorX == 6 || cursorX == 7)) #elif GERMAN if (namingScreenDataPtr->currentPage == PAGE_OTHERS && (cursorX == 6 || cursorX == 7 || cursorX == 8)) #endif { if (sDpadDeltaX[dpadDir] > 0) cursorX = COLUMN_COUNT - 1; else cursorX = 5; } if (cursorX == COLUMN_COUNT - 1) { //We are now on the last column task->tKbFunctionKey = cursorY; cursorY = s4RowTo3RowTableY[cursorY]; } else if (prevCursorX == COLUMN_COUNT - 1) { if (cursorY == 1) cursorY = task->tKbFunctionKey; else cursorY = gUnknown_083CE274[cursorY]; } } if (cursorX == COLUMN_COUNT - 1) { //There are only 3 keys on the last column, unlike the others, //so wrap Y accordingly if (cursorY < 0) cursorY = 2; if (cursorY > 2) cursorY = 0; if (cursorY == 0) task->tKbFunctionKey = FNKEY_BACK; else if (cursorY == 2) task->tKbFunctionKey = FNKEY_OK; } else { if (cursorY < 0) cursorY = 3; if (cursorY > 3) cursorY = 0; } SetCursorPos(cursorX, cursorY); } #undef tState #undef tKeyboardEvent #undef tKbFunctionKey //-------------------------------------------------- // //-------------------------------------------------- static void Task_80B64D4(u8); static u16 sub_80B654C(u8); static void sub_80B65AC(u8); static void sub_80B65D4(struct Task *, u8, u8); static void sub_80B6438(void) { u8 taskId; taskId = CreateTask(Task_80B64D4, 3); gTasks[taskId].data[0] = 3; } static void sub_80B6460(u8 a, u8 b, u8 c) { struct Task *task = &gTasks[FindTaskIdByFunc(Task_80B64D4)]; if (a == task->data[0] && c == 0) { task->data[1] = b; task->data[2] = 1; return; } if (a == 3 && task->data[1] == 0 && c == 0) return; if (task->data[0] != 3) sub_80B65AC(task->data[0]); sub_80B65D4(task, a, b); } static void Task_80B64D4(u8 taskId) { struct Task *task = &gTasks[taskId]; if (task->data[0] == 3 || task->data[2] == 0) return; MultiplyInvertedPaletteRGBComponents(sub_80B654C(task->data[0]), task->data[3], task->data[3], task->data[3]); if (task->data[5] != 0) { task->data[5]--; if (task->data[5] != 0) return; } task->data[5] = 2; task->data[3] += task->data[4]; if (task->data[3] == 16) task->data[4] = -task->data[4]; else if (task->data[3] == 0) { task->data[2] = task->data[1]; task->data[4] = -task->data[4]; } } static u16 sub_80B654C(u8 a) { const u16 arr[] = { IndexOfSpritePaletteTag(4) * 16 + 0x10E, IndexOfSpritePaletteTag(6) * 16 + 0x10C, IndexOfSpritePaletteTag(6) * 16 + 0x10E, }; return arr[a]; } static void sub_80B65AC(u8 a) { u16 index = sub_80B654C(a); gPlttBufferFaded[index] = gPlttBufferUnfaded[index]; } static void sub_80B65D4(struct Task *task, u8 b, u8 c) { task->data[0] = b; task->data[1] = c; task->data[2] = 1; task->data[3] = 15; task->data[4] = 1; task->data[5] = 0; } //-------------------------------------------------- // Page Swap //-------------------------------------------------- #define tState data[0] #define tFrameCount data[1] static bool8 PageSwapAnimState_Init(struct Task *); static bool8 PageSwapAnimState_1(struct Task *); static bool8 PageSwapAnimState_2(struct Task *); static bool8 PageSwapAnimState_Done(struct Task *); static bool8 (*const sPageSwapAnimStateFuncs[])(struct Task *) = { PageSwapAnimState_Init, PageSwapAnimState_1, PageSwapAnimState_2, PageSwapAnimState_Done, }; static void StartPageSwapAnim(void) { u8 taskId; taskId = CreateTask(Task_HandlePageSwapAnim, 0); Task_HandlePageSwapAnim(taskId); } static bool8 IsPageSwapAnimNotInProgress(void) { if (FindTaskIdByFunc(Task_HandlePageSwapAnim) == 0xFF) return TRUE; else return FALSE; } static void Task_HandlePageSwapAnim(u8 taskId) { while (sPageSwapAnimStateFuncs[gTasks[taskId].tState](&gTasks[taskId]) != 0) ; } static bool8 PageSwapAnimState_Init(struct Task *task) { namingScreenDataPtr->bg1vOffset = 0; namingScreenDataPtr->bg2vOffset = 0; task->tState++; return 0; } static bool8 PageSwapAnimState_1(struct Task *task) { u16 *const arr[] = { &namingScreenDataPtr->bg2vOffset, &namingScreenDataPtr->bg1vOffset }; task->tFrameCount += 4; *arr[namingScreenDataPtr->bgToReveal] = Sin(task->tFrameCount, 40); *arr[namingScreenDataPtr->bgToHide] = Sin((task->tFrameCount + 128) & 0xFF, 40); if (task->tFrameCount >= 64) { u8 temp = namingScreenDataPtr->bg1Priority; namingScreenDataPtr->bg1Priority = namingScreenDataPtr->bg2Priority; namingScreenDataPtr->bg2Priority = temp; task->tState++; } return 0; } static bool8 PageSwapAnimState_2(struct Task *task) { u16 *const arr[] = {&namingScreenDataPtr->bg2vOffset, &namingScreenDataPtr->bg1vOffset}; task->tFrameCount += 4; *arr[namingScreenDataPtr->bgToReveal] = Sin(task->tFrameCount, 40); *arr[namingScreenDataPtr->bgToHide] = Sin((task->tFrameCount + 128) & 0xFF, 40); if (task->tFrameCount >= 128) { u8 temp = namingScreenDataPtr->bgToReveal; namingScreenDataPtr->bgToReveal = namingScreenDataPtr->bgToHide; namingScreenDataPtr->bgToHide = temp; task->tState++; } return 0; } static bool8 PageSwapAnimState_Done(struct Task *task) { DestroyTask(FindTaskIdByFunc(Task_HandlePageSwapAnim)); return 0; } #undef tState #undef tFrameCount //-------------------------------------------------- // Cursor //-------------------------------------------------- static void CursorInit(void) { namingScreenDataPtr->cursorSpriteId = CreateSprite(&gSpriteTemplate_83CE640, 0, 0, 0); gSprites[namingScreenDataPtr->cursorSpriteId].oam.priority = 1; gSprites[namingScreenDataPtr->cursorSpriteId].oam.objMode = 1; gSprites[namingScreenDataPtr->cursorSpriteId].data[6] = 1; gSprites[namingScreenDataPtr->cursorSpriteId].data[6] = 2; SetCursorPos(0, 0); } static const u8 sKeyboardSymbolPositions[][COLUMN_COUNT] = { #if ENGLISH {1, 3, 5, 8, 10, 12, 14, 17, 19}, //Upper page {1, 3, 5, 8, 10, 12, 14, 17, 19}, //Lower page {1, 4, 7, 10, 13, 16, 16, 16, 19}, //Others page #elif GERMAN {2, 3, 4, 5, 9, 10, 11, 12, 16, 19}, //Upper page {2, 3, 4, 5, 9, 10, 11, 12, 16, 19}, //Lower page {1, 4, 7, 10, 13, 16, 16, 16, 16, 19}, //Others page #endif }; static u8 CursorColToKeyboardCol(s16 x) { return sKeyboardSymbolPositions[namingScreenDataPtr->currentPage][x]; } static void SetCursorPos(s16 x, s16 y) { struct Sprite *cursorSprite = &gSprites[namingScreenDataPtr->cursorSpriteId]; cursorSprite->x = CursorColToKeyboardCol(x) * 8 + 27; cursorSprite->y = y * 16 + 80; cursorSprite->data[2] = cursorSprite->data[0]; cursorSprite->data[3] = cursorSprite->data[1]; cursorSprite->data[0] = x; cursorSprite->data[1] = y; } static void GetCursorPos(s16 *x, s16 *y) { struct Sprite *cursorSprite = &gSprites[namingScreenDataPtr->cursorSpriteId]; *x = cursorSprite->data[0]; *y = cursorSprite->data[1]; } static void MoveCursorToOKButton(void) { SetCursorPos(COLUMN_COUNT - 1, 2); } static void sub_80B6888(u8 a) { gSprites[namingScreenDataPtr->cursorSpriteId].data[4] &= -256; gSprites[namingScreenDataPtr->cursorSpriteId].data[4] |= a; StartSpriteAnim(&gSprites[namingScreenDataPtr->cursorSpriteId], 0); } static void sub_80B68D8(u8 a) { gSprites[namingScreenDataPtr->cursorSpriteId].data[4] &= 0xFF; gSprites[namingScreenDataPtr->cursorSpriteId].data[4] |= a << 8; } static void sub_80B6914(void) { StartSpriteAnim(&gSprites[namingScreenDataPtr->cursorSpriteId], 1); } static bool8 IsCursorAnimFinished(void) { return gSprites[namingScreenDataPtr->cursorSpriteId].animEnded; } static u8 GetKeyRoleAtCursorPos(void) { const u8 keyRoles[] = {KEY_ROLE_PAGE, KEY_ROLE_BACKSPACE, KEY_ROLE_OK}; s16 cursorX; s16 cursorY; GetCursorPos(&cursorX, &cursorY); if (cursorX < COLUMN_COUNT - 1) return KEY_ROLE_CHAR; else return keyRoles[cursorY]; } void sub_80B6998(struct Sprite *sprite) { if (sprite->animEnded) StartSpriteAnim(sprite, 0); sprite->invisible = (sprite->data[4] & 0xFF); if (sprite->data[0] == COLUMN_COUNT - 1) sprite->invisible = TRUE; if (sprite->invisible || (sprite->data[4] & 0xFF00) == 0 || sprite->data[0] != sprite->data[2] || sprite->data[1] != sprite->data[3]) { sprite->data[5] = 0; sprite->data[6] = 1; sprite->data[7] = 2; } sprite->data[7]--; if (sprite->data[7] == 0) { sprite->data[5] += sprite->data[6]; if (sprite->data[5] == 16 || sprite->data[5] == 0) sprite->data[6] = -sprite->data[6]; sprite->data[7] = 2; } if ((sprite->data[4] & 0xFF00) != 0) { s8 gb = sprite->data[5]; s8 r = sprite->data[5] >> 1; u16 index = IndexOfSpritePaletteTag(5) * 16 + 0x0101; MultiplyInvertedPaletteRGBComponents(index, r, gb, gb); } } static void sub_80B6A80(void) { u8 spriteId1; u8 spriteId2; u8 spriteId3; spriteId1 = CreateSprite(&gSpriteTemplate_83CE5C8, 0xCC, 0x50, 0); namingScreenDataPtr->pageIndicatorSpriteId = spriteId1; SetSubspriteTables(&gSprites[spriteId1], gSubspriteTables_83CE558); spriteId2 = CreateSprite(&gSpriteTemplate_83CE5F8, 0xCC, 0x4C, 1); gSprites[spriteId1].data[6] = spriteId2; SetSubspriteTables(&gSprites[spriteId2], gSubspriteTables_83CE560); spriteId3 = CreateSprite(&gSpriteTemplate_83CE5E0, 0xCC, 0x4B, 2); gSprites[spriteId3].oam.priority = 1; gSprites[spriteId1].data[7] = spriteId3; } static void sub_80B6B14(void) { struct Sprite *sprite = &gSprites[namingScreenDataPtr->pageIndicatorSpriteId]; sprite->data[0] = 2; sprite->data[1] = namingScreenDataPtr->currentPage; } static u8 sub_80B6B5C(struct Sprite *); static u8 sub_80B6B98(struct Sprite *); static u8 sub_80B6B9C(struct Sprite *); static u8 sub_80B6C08(struct Sprite *); static u8 (*const gUnknown_083CE2B4[])(struct Sprite *) = { sub_80B6B5C, sub_80B6B98, sub_80B6B9C, sub_80B6C08, }; void sub_80B6B34(struct Sprite *sprite) { while (gUnknown_083CE2B4[sprite->data[0]](sprite) != 0) ; } static u8 sub_80B6B5C(struct Sprite *sprite) { struct Sprite *sprite1 = &gSprites[sprite->data[6]]; struct Sprite *sprite2 = &gSprites[sprite->data[7]]; sub_80B6C48(namingScreenDataPtr->currentPage, sprite1, sprite2); sprite->data[0]++; return 0; } static u8 sub_80B6B98(struct Sprite *sprite) { return 0; } static u8 sub_80B6B9C(struct Sprite *sprite) { struct Sprite *r4 = &gSprites[sprite->data[6]]; struct Sprite *r5 = &gSprites[sprite->data[7]]; r4->y2++; if (r4->y2 > 7) { sprite->data[0]++; r4->y2 = -4; r4->invisible = TRUE; sub_80B6C48(((u8)sprite->data[1] + 1) % 3, r4, r5); } return 0; } static u8 sub_80B6C08(struct Sprite *sprite) { struct Sprite *r2 = &gSprites[sprite->data[6]]; r2->invisible = FALSE; r2->y2++; if (r2->y2 >= 0) { r2->y2 = 0; sprite->data[0] = 1; } return 0; } static const u16 gUnknown_083CE2C4[] = {1, 3, 2}; static const u16 gUnknown_083CE2CA[] = {4, 6, 5}; static void sub_80B6C48(u8 a, struct Sprite *b, struct Sprite *c) { c->oam.paletteNum = IndexOfSpritePaletteTag(gUnknown_083CE2C4[a]); b->sheetTileStart = GetSpriteTileStartByTag(gUnknown_083CE2CA[a]); b->subspriteTableNum = a; } // static void sub_80B6CA8(void) { u8 spriteId; spriteId = CreateSprite(&gSpriteTemplate_83CE610, 0xCC, 0x6C, 0); SetSubspriteTables(&gSprites[spriteId], gSubspriteTables_83CE578); spriteId = CreateSprite(&gSpriteTemplate_83CE628, 0xCC, 0x84, 0); SetSubspriteTables(&gSprites[spriteId], gSubspriteTables_83CE578); } static void sub_80B6D04(void) { u8 spriteId; s16 left; u8 i; left = (namingScreenDataPtr->nameLeftOffset - 1) * 8 + 4; spriteId = CreateSprite(&gSpriteTemplate_83CE658, left, 0x28, 0); gSprites[spriteId].oam.priority = 3; left = namingScreenDataPtr->nameLeftOffset * 8 + 4; for (i = 0; i < namingScreenDataPtr->template->maxChars; i++, left += 8) { spriteId = CreateSprite(&gSpriteTemplate_83CE670, left, 0x2C, 0); gSprites[spriteId].oam.priority = 3; gSprites[spriteId].data[0] = i; } } void sub_80B6D9C(struct Sprite *sprite) { const s16 arr[] = {0, -4, -2, -1}; if (sprite->data[0] == 0 || --sprite->data[0] == 0) { sprite->data[0] = 8; sprite->data[1] = (sprite->data[1] + 1) & 3; } sprite->x2 = arr[sprite->data[1]]; } void sub_80B6DE8(struct Sprite *sprite) { const s16 arr[] = {2, 3, 2, 1}; u8 var; var = GetTextCaretPosition(); if (var != (u8)sprite->data[0]) { sprite->y2 = 0; sprite->data[1] = 0; sprite->data[2] = 0; } else { sprite->y2 = arr[sprite->data[1]]; sprite->data[2]++; if (sprite->data[2] > 8) { sprite->data[1] = (sprite->data[1] + 1) & 3; sprite->data[2] = 0; } } } // static void nullsub_40(void); static void sub_80B6E68(void); static void sub_80B6EBC(void); static void sub_80B6EFC(void); static void (*const gUnknown_083CE2E0[])(void) = { nullsub_40, sub_80B6E68, sub_80B6EBC, sub_80B6EFC, }; static void sub_80B6E44(void) { gUnknown_083CE2E0[namingScreenDataPtr->template->iconFunction](); } static void nullsub_40(void) { } static void sub_80B6E68(void) { u8 rivalGfxId; u8 spriteId; rivalGfxId = GetRivalAvatarGraphicsIdByStateIdAndGender(PLAYER_AVATAR_STATE_NORMAL, namingScreenDataPtr->speciesOrPlayerGender); spriteId = AddPseudoObjectEvent(rivalGfxId, SpriteCallbackDummy, 0x38, 0x18, 0); gSprites[spriteId].oam.priority = 3; StartSpriteAnim(&gSprites[spriteId], 4); } static void sub_80B6EBC(void) { u8 spriteId; spriteId = CreateSprite(&gSpriteTemplate_83CE688, 0x34, 0x18, 0); SetSubspriteTables(&gSprites[spriteId], gSubspriteTables_83CE580); gSprites[spriteId].oam.priority = 3; } static void sub_80B6EFC(void) { u8 spriteId; sub_809D51C(); spriteId = CreateMonIcon(namingScreenDataPtr->speciesOrPlayerGender, SpriteCallbackDummy, 0x34, 0x18, 0, namingScreenDataPtr->monPersonality); gSprites[spriteId].oam.priority = 3; } static u8 GetTextCaretPosition(void) { u8 i; for (i = 0; i < namingScreenDataPtr->template->maxChars; i++) { if (namingScreenDataPtr->textBuffer[i] == EOS) return i; } return namingScreenDataPtr->template->maxChars - 1; } static u8 GetPreviousTextCaretPosition(void) { s8 i; for (i = namingScreenDataPtr->template->maxChars - 1; i > 0; i--) { if (namingScreenDataPtr->textBuffer[i] != EOS) return i; } return 0; } static void DeleteTextCharacter(void) { u8 index; u8 var2; index = GetPreviousTextCaretPosition(); namingScreenDataPtr->textBuffer[index] = 0; sub_80B7960(); namingScreenDataPtr->textBuffer[index] = EOS; var2 = GetKeyRoleAtCursorPos(); if (var2 == 0 || var2 == 2) sub_80B6460(1, 0, 1); PlaySE(SE_BALL); } static bool8 sub_80B7004(void) { s16 x; s16 y; u8 ch; bool8 r4; GetCursorPos(&x, &y); x = CursorColToKeyboardCol(x); ch = GetCharAtKeyboardPos(x, y); r4 = 1; if (ch == 0xFF) r4 = sub_80B7104(); else if (ch == 0xFE) r4 = sub_80B713C(); else AddTextCharacter(ch); sub_80B7960(); PlaySE(SE_SELECT); if (r4) { if (GetPreviousTextCaretPosition() == namingScreenDataPtr->template->maxChars - 1) return TRUE; } return FALSE; } static void sub_80B7090(void) // DoInput? { u8 r5; u8 r4; r5 = GetPreviousTextCaretPosition(); r4 = namingScreenDataPtr->textBuffer[r5]; if (sub_80B7198(r4)) { if (sub_80B7264(r4)) sub_80B7370(r4, r5); else sub_80B73CC(r4, r5); } else { if (sub_80B71E4(r4)) sub_80B7474(r4, r5); else sub_80B72A4(r4, r5); } sub_80B7960(); PlaySE(SE_SELECT); } static bool8 sub_80B7104(void) { u8 r5; u8 r4; r5 = GetPreviousTextCaretPosition(); r4 = namingScreenDataPtr->textBuffer[r5]; if (sub_80B720C(r4)) { sub_80B72A4(r4, r5); return TRUE; } return FALSE; } static bool8 sub_80B713C(void) { u8 r5; u8 r4; r5 = GetPreviousTextCaretPosition(); r4 = namingScreenDataPtr->textBuffer[r5]; if (sub_80B7264(r4)) { sub_80B7370(r4, r5); return TRUE; } return FALSE; } static void AddTextCharacter(u8 ch) { u8 index = GetTextCaretPosition(); namingScreenDataPtr->textBuffer[index] = ch; } static bool8 sub_80B7198(u8 a) { if ((a >= 55 && a <= 74) || (a >= 135 && a <= 139) || (a >= 140 && a <= 144) || (a >= 145 && a <= 149) || (a >= 150 && a <= 154)) return TRUE; else return FALSE; } static bool8 sub_80B71E4(u8 a) { if ((a >= 75 && a <= 79) || (a >= 155 && a <= 159)) return TRUE; else return FALSE; } static bool8 sub_80B720C(u8 a) { if ((a >= 6 && a <= 20) || (a >= 26 && a <= 30) || (a >= 75 && a <= 79) || (a >= 86 && a <= 100) || (a >= 106 && a <= 110) || (a >= 155 && a <= 159)) return TRUE; else return FALSE; } static bool8 sub_80B7264(u8 a) { if ((a >= 26 && a <= 30) || (a >= 70 && a <= 74) || (a >= 106 && a <= 110) || (a >= 150 && a <= 154)) return TRUE; else return FALSE; } static void sub_80B72A4(u8 a, u8 b) { u8 chr = a; if (a >= 6 && a <= 10) chr = a + 0x31; else if (a >= 11 && a <= 15) chr = a + 0x31; else if (a >= 16 && a <= 20) chr = a + 0x31; else if (a >= 26 && a <= 30) chr = a + 0x2C; else if (a >= 75 && a <= 79) chr = a + 0xFB; else if (a >= 86 && a <= 90) chr = a + 0x31; else if (a >= 91 && a <= 95) chr = a + 0x31; else if (a >= 96 && a <= 100) chr = a + 0x31; else if (a >= 106 && a <= 110) chr = a + 0x2C; else if (a >= 155 && a <= 159) chr = a + 0xFB; namingScreenDataPtr->textBuffer[b] = chr; } static void sub_80B7370(u8 a, u8 b) { u8 chr = a; if (a >= 26 && a <= 30) chr = a + 0x31; else if (a >= 70 && a <= 74) chr = a + 5; else if (a >= 106 && a <= 110) chr = a + 0x31; else if (a >= 150 && a <= 154) chr = a + 5; namingScreenDataPtr->textBuffer[b] = chr; } static void sub_80B73CC(u8 a, u8 b) { u8 chr = a; if (a >= 55 && a <= 59) chr = a + 0xCF; else if (a >= 60 && a <= 64) chr = a + 0xCF; else if (a >= 65 && a <= 69) chr = a + 0xCF; else if (a >= 70 && a <= 74) chr = a + 0xD4; else if (a >= 135 && a <= 139) chr = a + 0xCF; else if (a >= 140 && a <= 144) chr = a + 0xCF; else if (a >= 145 && a <= 149) chr = a + 0xCF; else if (a >= 150 && a <= 154) chr = a + 0xD4; namingScreenDataPtr->textBuffer[b] = chr; } static void sub_80B7474(u8 a, u8 b) { u8 chr = a; if (a >= 75 && a <= 79) chr = a + 0xCF; else if (a >= 155 && a <= 159) chr = a + 0xCF; namingScreenDataPtr->textBuffer[b] = chr; } static void sub_80B74B0(void) { u8 i; for (i = 0; i < namingScreenDataPtr->template->maxChars; i++) { if (namingScreenDataPtr->textBuffer[i] != 0 && namingScreenDataPtr->textBuffer[i] != 0xFF) { StringCopyN(namingScreenDataPtr->destBuffer, namingScreenDataPtr->textBuffer, namingScreenDataPtr->template->maxChars + 1); break; } } } static void DisplaySentToPCMessage(void) { StringCopy(gStringVar1, namingScreenDataPtr->destBuffer); StringExpandPlaceholders(gStringVar4, gOtherText_SentToPC); BasicInitMenuWindow(&gWindowTemplate_81E6E88); Menu_DisplayDialogueFrame(); MenuPrintMessageDefaultCoords(gStringVar4); } static void sub_80B753C(void) { LoadSpriteSheets(gUnknown_083CE6A0); LoadSpritePalettes(gUnknown_083CE708); } static void sub_80B7558(void) { sub_80B7568(); sub_80B75B0(); } static void sub_80B7568(void) { DmaCopy16Defvars(3, gNamingScreenMenu_Gfx, (void *)(VRAM + gMenuMessageBoxContentTileOffset * 32), 0x800); DmaCopy16Defvars(3, gNamingScreenMenu_Gfx, (void *)(VRAM + 0x8000 + gMenuMessageBoxContentTileOffset * 32), 0x800); } static void sub_80B75B0(void) { LoadPalette(gNamingScreenPalettes, 0, 0x80); } static void sub_80B7650(u16 *); static void sub_80B7660(u16 *); static void sub_80B7670(u16 *); static void (*const gUnknown_083CE2F0[][2])(u16 *) = { {sub_80B7660, sub_80B7650}, {sub_80B7650, sub_80B7670}, {sub_80B7670, sub_80B7660}, }; static void sub_80B75C4(void) { u16 *const arr[] = { (u16 *)(VRAM + 0xE000), (u16 *)(VRAM + 0xE800), }; gUnknown_083CE2F0[namingScreenDataPtr->currentPage][0](arr[namingScreenDataPtr->bgToReveal]); gUnknown_083CE2F0[namingScreenDataPtr->currentPage][1](arr[namingScreenDataPtr->bgToHide]); } static void sub_80B7614(void) { u16 *const arr[] = { (u16 *)(VRAM + 0xE000), (u16 *)(VRAM + 0xE800), }; gUnknown_083CE2F0[namingScreenDataPtr->currentPage][1](arr[namingScreenDataPtr->bgToHide]); } static void sub_80B7650(u16 *vramBuffer) { sub_80B7698(vramBuffer, gUnknown_083CE748); } static void sub_80B7660(u16 *vramBuffer) { sub_80B7698(vramBuffer, gUnknown_083CEBF8); } static void sub_80B7670(u16 *vramBuffer) { sub_80B7698(vramBuffer, gUnknown_083CF0A8); } static void sub_80B7680(void) { sub_80B76E0(VRAM + 0xF000, gUnknown_08E86258); } static void sub_80B7698(u16 *vramBuffer, const u16 *src) { s16 i; s16 j; for (i = 0; i < 20; i++) { for (j = 0; j < 30; j++, src++) { vramBuffer[i * 32 + j] = *src + gMenuMessageBoxContentTileOffset; } } } static void sub_80B76E0(u16 *vramBuffer, const u16 *src) { s16 i; s16 j; for (i = 0; i < 20; i++) { for (j = 0; j < 30; j++, src++) { vramBuffer[i * 32 + j] = *src + gMenuMessageBoxContentTileOffset; } src += 2; } } static void sub_80B772C(void) { nullsub_20(namingScreenDataPtr->currentPage, namingScreenDataPtr->bgToReveal); } static void sub_80B7740(void) { nullsub_20((namingScreenDataPtr->currentPage + 1) % 3, namingScreenDataPtr->bgToHide); } static void nullsub_20(u8 a, u8 b) { } static void sub_80B7838(void); static void sub_80B7844(void); static void sub_80B7850(void); static void (*const gUnknown_083CE310[][2])(void) = { sub_80B7844, sub_80B7838, sub_80B7838, sub_80B7850, sub_80B7850, sub_80B7844, }; static const struct WindowTemplate *const gUnknown_083CE328[][2][2] = { { {&gWindowTemplate_81E6EDC, &gWindowTemplate_81E6EF8}, {&gWindowTemplate_81E6EA4, &gWindowTemplate_81E6EC0}, }, { {&gWindowTemplate_81E6EA4, &gWindowTemplate_81E6EC0}, {&gWindowTemplate_81E6F14, &gWindowTemplate_81E6F30}, }, { {&gWindowTemplate_81E6F14, &gWindowTemplate_81E6F30}, {&gWindowTemplate_81E6EDC, &gWindowTemplate_81E6EF8}, }, }; static void nullsub_61(void); static void sub_80B78F8(void); static void (*const gUnknown_083CE358[])(void) = { nullsub_61, nullsub_61, sub_80B78F8, sub_80B78F8, }; static void nullsub_62(void); static void sub_80B7924(void); static void (*const gUnknown_083CE368[])(void) = { nullsub_62, sub_80B7924, }; static const u8 sKeyboardCharacters[][4][20]; //forward declaration static u8 GetCharAtKeyboardPos(s16 a, s16 b) { return sKeyboardCharacters[namingScreenDataPtr->currentPage][b][a]; } static void sub_80B7794(void) { BasicInitMenuWindow(gUnknown_083CE328[namingScreenDataPtr->currentPage][0][namingScreenDataPtr->bgToReveal]); gUnknown_083CE310[namingScreenDataPtr->currentPage][0](); BasicInitMenuWindow(gUnknown_083CE328[namingScreenDataPtr->currentPage][1][namingScreenDataPtr->bgToHide]); gUnknown_083CE310[namingScreenDataPtr->currentPage][1](); sub_80B772C(); sub_80B7740(); } static void sub_80B77F8(void) { BasicInitMenuWindow(gUnknown_083CE328[namingScreenDataPtr->currentPage][1][namingScreenDataPtr->bgToHide]); gUnknown_083CE310[namingScreenDataPtr->currentPage][1](); sub_80B7740(); } static void sub_80B7838(void) { PrintKeyboardCharacters(1); } static void sub_80B7844(void) { PrintKeyboardCharacters(0); } static void sub_80B7850(void) { PrintKeyboardCharacters(2); } static void PrintKeyboardCharacters(u8 page) //print letters on page { s16 i; s16 r5; for (i = 0, r5 = 9; i < 4; i++, r5 += 2) Menu_PrintText(sKeyboardCharacters[page][i], 3, r5); } static void sub_80B78A8(void) { BasicInitMenuWindow(&gWindowTemplate_81E6F4C); gUnknown_083CE358[namingScreenDataPtr->templateNum](); gUnknown_083CE368[namingScreenDataPtr->template->addGenderIcon](); Menu_PrintText(namingScreenDataPtr->template->title, 9, 2); } static void nullsub_61(void) { } static void sub_80B78F8(void) { StringCopy(gStringVar1, gSpeciesNames[(s16)namingScreenDataPtr->speciesOrPlayerGender]); } static void nullsub_62(void) { } static void sub_80B7924(void) { u8 genderSymbol[2] = _("♂"); if ((s16)namingScreenDataPtr->monGender != MON_GENDERLESS) { if ((s16)namingScreenDataPtr->monGender == MON_FEMALE) genderSymbol[0] = 0xB6; //female symbol Menu_PrintText(genderSymbol, 0x14, 4); } } static void sub_80B7960(void) { u8 *string = gStringVar1; string[0] = 0xFC; string[1] = 0x14; string[2] = 8; string[3] = 0xFC; string[4] = 0x11; string[5] = 1; string += 6; StringCopy(string, namingScreenDataPtr->textBuffer); BasicInitMenuWindow(&gWindowTemplate_81E6F4C); Menu_PrintText(gStringVar1, namingScreenDataPtr->nameLeftOffset, 4); } //-------------------------------------------------- // Forward-declared variables //-------------------------------------------------- static const struct NamingScreenTemplate playerNamingScreenTemplate = { .copyExistingString = 0, .maxChars = 7, .iconFunction = 1, .addGenderIcon = 0, .initialPage = 0, .title = OtherText_YourName, }; static const struct NamingScreenTemplate pcBoxNamingTemplate = { .copyExistingString = 0, .maxChars = 8, .iconFunction = 2, .addGenderIcon = 0, .initialPage = 0, .title = OtherText_BoxName, }; static const struct NamingScreenTemplate monNamingScreenTemplate = { .copyExistingString = 0, .maxChars = 10, .iconFunction = 3, .addGenderIcon = 1, .initialPage = 0, .title = OtherText_PokeName, }; static const struct NamingScreenTemplate *const sNamingScreenTemplates[] = { &playerNamingScreenTemplate, &pcBoxNamingTemplate, &monNamingScreenTemplate, &monNamingScreenTemplate, }; static const u8 sKeyboardCharacters[][4][20] = { #if ENGLISH { _(" A B C D E F . "), _(" G H I J K L , "), _(" M N O P Q R S "), _(" T U V W X Y Z "), }, { _(" a b c d e f . "), _(" g h i j k l , "), _(" m n o p q r s "), _(" t u v w x y z "), }, #elif GERMAN { _(" ABCD EFGH . "), _(" IJKL MNOP , "), _(" QRST UVWX "), _(" YZ ÄÖÜ "), }, { _(" abcd efgh . "), _(" ijkl mnop , "), _(" qrst uvwx "), _(" yz äöü "), }, #endif { _(" 0 1 2 3 4 "), _(" 5 6 7 8 9 "), _(" ! ? ♂ ♀ / - "), _(" … “ ” ‘ ' "), }, }; const struct OamData gOamData_83CE498 = { .y = 0, .affineMode = 0, .objMode = 0, .mosaic = 0, .bpp = 0, .shape = 0, .x = 0, .matrixNum = 0, .size = 0, .tileNum = 0, .priority = 0, .paletteNum = 0, .affineParam = 0, }; const struct OamData gOamData_83CE4A0 = { .y = 0, .affineMode = 0, .objMode = 0, .mosaic = 0, .bpp = 0, .shape = 0, .x = 0, .matrixNum = 0, .size = 1, .tileNum = 0, .priority = 0, .paletteNum = 0, .affineParam = 0, }; const struct OamData gOamData_83CE4A8 = { .y = 0, .affineMode = 0, .objMode = 0, .mosaic = 0, .bpp = 0, .shape = 1, .x = 0, .matrixNum = 0, .size = 2, .tileNum = 0, .priority = 0, .paletteNum = 0, .affineParam = 0, }; const struct Subsprite gSubspriteTable_83CE4B0[] = { { -20, -16, ST_OAM_H_RECTANGLE, 1, 0, 1 }, { 12, -16, ST_OAM_SQUARE, 0, 4, 1 }, { -20, -8, ST_OAM_H_RECTANGLE, 1, 5, 1 }, { 12, -8, ST_OAM_SQUARE, 0, 9, 1 }, { -20, 0, ST_OAM_H_RECTANGLE, 1, 10, 1 }, { 12, 0, ST_OAM_SQUARE, 0, 14, 1 }, { -20, 8, ST_OAM_H_RECTANGLE, 1, 15, 1 }, { 12, 8, ST_OAM_SQUARE, 0, 19, 1 } }; const struct Subsprite gSubspriteTable_83CE4F0[] = { { -12, -4, ST_OAM_SQUARE, 0, 0, 1 }, { 4, -4, ST_OAM_SQUARE, 0, 1, 1 } }; const struct Subsprite gSubspriteTable_83CE500[] = { { -12, -4, ST_OAM_H_RECTANGLE, 0, 0, 1 }, { 4, -4, ST_OAM_SQUARE, 0, 2, 1 } }; const struct Subsprite gSubspriteTable_83CE510[] = { { -20, -12, ST_OAM_H_RECTANGLE, 1, 0, 1 }, { 12, -12, ST_OAM_SQUARE, 0, 4, 1 }, { -20, -4, ST_OAM_H_RECTANGLE, 1, 5, 1 }, { 12, -4, ST_OAM_SQUARE, 0, 9, 1 }, { -20, 4, ST_OAM_H_RECTANGLE, 1, 10, 1 }, { 12, 4, ST_OAM_SQUARE, 0, 14, 1 } }; const struct Subsprite gSubspriteTable_83CE540[] = { { -8, -12, ST_OAM_H_RECTANGLE, 0, 0, 3 }, { -8, -4, ST_OAM_H_RECTANGLE, 0, 2, 3 }, { -8, 4, ST_OAM_H_RECTANGLE, 0, 4, 3 } }; const struct SubspriteTable gSubspriteTables_83CE558[] = { { 8, gSubspriteTable_83CE4B0 } }; const struct SubspriteTable gSubspriteTables_83CE560[] = { { 2, gSubspriteTable_83CE500 }, { 2, gSubspriteTable_83CE500 }, { 2, gSubspriteTable_83CE500 } }; const struct SubspriteTable gSubspriteTables_83CE578[] = { { 6, gSubspriteTable_83CE510 } }; const struct SubspriteTable gSubspriteTables_83CE580[] = { { 3, gSubspriteTable_83CE540 } }; const struct SpriteFrameImage gSpriteImageTable_83CE588[] = { { gSpriteImage_83CE094, 0xc0 }, { gSpriteImage_83CE154, 0xc0 } }; const union AnimCmd gSpriteAnim_83CE598[] = { ANIMCMD_FRAME(0, 1), ANIMCMD_JUMP(0) }; const union AnimCmd gSpriteAnim_83CE5A0[] = { ANIMCMD_FRAME(4, 8), ANIMCMD_FRAME(8, 8), ANIMCMD_END }; const union AnimCmd gSpriteAnim_83CE5AC[] = { ANIMCMD_FRAME(0, 2), ANIMCMD_FRAME(1, 2), ANIMCMD_JUMP(0) }; const union AnimCmd *const gSpriteAnimTable_83CE5B8[] = { gSpriteAnim_83CE598 }; const union AnimCmd *const gSpriteAnimTable_83CE5BC[] = { gSpriteAnim_83CE598, gSpriteAnim_83CE5A0 }; const union AnimCmd *const gSpriteAnimTable_83CE5C4[] = { gSpriteAnim_83CE5AC }; const struct SpriteTemplate gSpriteTemplate_83CE5C8 = { 2, 4, &gOamData_83CE498, gSpriteAnimTable_83CE5B8, NULL, gDummySpriteAffineAnimTable, sub_80B6B34 }; const struct SpriteTemplate gSpriteTemplate_83CE5E0 = { 3, 1, &gOamData_83CE4A8, gSpriteAnimTable_83CE5B8, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy }; const struct SpriteTemplate gSpriteTemplate_83CE5F8 = { 4, 4, &gOamData_83CE498, gSpriteAnimTable_83CE5B8, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy }; const struct SpriteTemplate gSpriteTemplate_83CE610 = { 0, 6, &gOamData_83CE498, gSpriteAnimTable_83CE5B8, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy }; const struct SpriteTemplate gSpriteTemplate_83CE628 = { 1, 6, &gOamData_83CE498, gSpriteAnimTable_83CE5B8, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy }; const struct SpriteTemplate gSpriteTemplate_83CE640 = { 7, 5, &gOamData_83CE4A0, gSpriteAnimTable_83CE5BC, NULL, gDummySpriteAffineAnimTable, sub_80B6998 }; const struct SpriteTemplate gSpriteTemplate_83CE658 = { 10, 3, &gOamData_83CE498, gSpriteAnimTable_83CE5B8, NULL, gDummySpriteAffineAnimTable, sub_80B6D9C }; const struct SpriteTemplate gSpriteTemplate_83CE670 = { 11, 3, &gOamData_83CE498, gSpriteAnimTable_83CE5B8, NULL, gDummySpriteAffineAnimTable, sub_80B6DE8 }; const struct SpriteTemplate gSpriteTemplate_83CE688 = { 0xFFFF, 0, &gOamData_83CE498, gSpriteAnimTable_83CE5C4, gSpriteImageTable_83CE588, gDummySpriteAffineAnimTable, SpriteCallbackDummy }; const struct SpriteSheet gUnknown_083CE6A0[] = { { gNamingScreenBackButtonTiles, 0x1E0, 0 }, { gNamingScreenOKButtonTiles, 0x1E0, 1 }, { gNamingScreenChangeKeyboardBoxTiles, 0x280, 2 }, { gNamingScreenChangeKeyboardButtonTiles, 0x100, 3 }, { gNamingScreenLowerTextTiles, 0x60, 4 }, { gNamingScreenUpperTextTiles, 0x60, 5 }, { gNamingScreenOthersTextTiles, 0x60, 6 }, { gNamingScreenCursorTiles, 0x80, 7 }, { gNamingScreenActiveCursorSmallTiles, 0x80, 8 }, { gNamingScreenActiveCursorBigTiles, 0x80, 9 }, { gNamingScreenRightPointingTriangleTiles, 0x20, 10 }, { gNamingScreenUnderscoreTiles, 0x20, 11 }, {} }; const struct SpritePalette gUnknown_083CE708[] = { {gNamingScreenPalettes[0], 0}, {gNamingScreenPalettes[1], 1}, {gNamingScreenPalettes[2], 2}, {gNamingScreenPalettes[3], 3}, {gNamingScreenPalettes[4], 4}, {gNamingScreenPalettes[5], 5}, {gNamingScreenPalettes[4], 6}, {} }; const u16 gUnknown_083CE748[] = INCBIN_U16("graphics/naming_screen/lower_keyboard_map.bin"); const u16 gUnknown_083CEBF8[] = INCBIN_U16("graphics/naming_screen/upper_keyboard_map.bin"); const u16 gUnknown_083CF0A8[] = INCBIN_U16("graphics/naming_screen/others_keyboard_map.bin");