diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dewford_trend.c | 340 | ||||
-rw-r--r-- | src/mail.c | 6 | ||||
-rw-r--r-- | src/naming_screen.c | 124 | ||||
-rw-r--r-- | src/pokemon_icon.c | 304 |
4 files changed, 709 insertions, 65 deletions
diff --git a/src/dewford_trend.c b/src/dewford_trend.c new file mode 100644 index 000000000..3ceec6563 --- /dev/null +++ b/src/dewford_trend.c @@ -0,0 +1,340 @@ +#include "global.h" +#include "dewford_trend.h" +#include "easy_chat.h" +#include "constants/easy_chat.h" +#include "event_data.h" +#include "link.h" +#include "malloc.h" +#include "random.h" +#include "text.h" +#include "tv.h" + +// static functions +static void sub_8122804(struct EasyChatPair *s, u16 b, u8 c); +static bool8 sub_8122A58(struct EasyChatPair *a, struct EasyChatPair *b, u8 c); +static void sub_8122B28(struct EasyChatPair *s); +static bool8 SB1ContainsWords(u16 *a); +static bool8 IsEasyChatPairEqual(u16 *words1, u16 *words2); +static s16 GetEqualEasyChatPairIndex(struct EasyChatPair *s, struct EasyChatPair *a, u16 b); + +// text +void InitDewfordTrend(void) +{ + u16 i; + + for (i = 0; i < 5; i++) + { + gSaveBlock1Ptr->easyChatPairs[i].words[0] = sub_811EE38(EC_GROUP_CONDITIONS); + + if (Random() & 1) + gSaveBlock1Ptr->easyChatPairs[i].words[1] = sub_811EE38(EC_GROUP_LIFESTYLE); + else + gSaveBlock1Ptr->easyChatPairs[i].words[1] = sub_811EE38(EC_GROUP_HOBBIES); + + gSaveBlock1Ptr->easyChatPairs[i].unk1_6 = Random() & 1; + sub_8122B28(&(gSaveBlock1Ptr->easyChatPairs[i])); + } + sub_8122804(gSaveBlock1Ptr->easyChatPairs, 5, 0); +} + +void UpdateDewfordTrendPerDay(u16 a) +{ + u16 i; + + if (a != 0) + { + u32 sp0 = a * 5; + + for (i = 0; i < 5; i++) + { + u32 r4; + u32 r2 = sp0; + struct EasyChatPair *r5 = &(gSaveBlock1Ptr->easyChatPairs[i]); + + if (r5->unk1_6 == 0) + { + if (r5->unk0_0 >= (u16)r2) + { + r5->unk0_0 -= r2; + if (r5->unk0_0 == 0) + r5->unk1_6 = 1; + continue; + } + r2 -= r5->unk0_0; + r5->unk0_0 = 0; + r5->unk1_6 = 1; + } + r4 = r5->unk0_0 + r2; + if ((u16)r4 > r5->unk0_7) + { + u32 sp4 = r4 % r5->unk0_7; + r4 = r4 / r5->unk0_7; + + r5->unk1_6 = r4 ^ 1; + if (r5->unk1_6) + r5->unk0_0 = sp4; + else + r5->unk0_0 = r5->unk0_7 - sp4; + } + else + { + r5->unk0_0 = r4; + + if (r5->unk0_0 == r5->unk0_7) + r5->unk1_6 = 0; + } + } + sub_8122804(gSaveBlock1Ptr->easyChatPairs, 5, 0); + } +} + + +bool8 sub_81226D8(u16 *a) +{ + struct EasyChatPair s = {0}; + u16 i; + + if (!SB1ContainsWords(a)) + { + if (!FlagGet(FLAG_SYS_POPWORD_INPUT)) + { + FlagSet(FLAG_SYS_POPWORD_INPUT); + if (!FlagGet(FLAG_SYS_MIX_RECORD)) + { + gSaveBlock1Ptr->easyChatPairs[0].words[0] = a[0]; + gSaveBlock1Ptr->easyChatPairs[0].words[1] = a[1]; + return TRUE; + } + } + + s.words[0] = a[0]; + s.words[1] = a[1]; + s.unk1_6 = 1; + sub_8122B28(&s); + + for (i = 0; i < 5; i++) + { + if (sub_8122A58(&s, &(gSaveBlock1Ptr->easyChatPairs[i]), 0)) + { + u16 r3 = 4; + + while (r3 > i) + { + gSaveBlock1Ptr->easyChatPairs[r3] = gSaveBlock1Ptr->easyChatPairs[r3 - 1]; + r3--; + } + gSaveBlock1Ptr->easyChatPairs[i] = s; + if(i == 4) + sub_80EDC60(a); + return (i == 0); + } + } + gSaveBlock1Ptr->easyChatPairs[4] = s; + sub_80EDC60(a); + } + return FALSE; +} + + +static void sub_8122804(struct EasyChatPair *s, u16 b, u8 c) +{ + u16 h; + + for (h = 0; h < b; h++) + { + u16 i; + + for (i = h + 1; i < b; i++) + { + if (sub_8122A58(&s[i], &s[h], c)) + { + struct EasyChatPair temp; + + temp = s[i]; + s[i] = s[h]; + s[h] = temp; + } + } + } +} + +void sub_812287C(void *a, u32 b, u8 unused) +{ + u16 i, j, r3, players; + struct EasyChatPair *buffer1, *buffer2, *src, *dst, *foo_of_buffer2; + + buffer1 = Alloc(0x100); + if(buffer1 != NULL) + { + buffer2 = Alloc(0x100); + if(buffer2 == NULL) + { + Free(buffer1); + } + else + { + players = GetLinkPlayerCount(); + for (i = 0; i < players; i++) + memcpy(&(buffer1[i * 5]), (u8 *)a + i * b, 40); + src = buffer1; + dst = buffer2; + r3 = 0; + for (i = 0; i < players; i++) + { + for (j = 0; j < 5; j++) + { + s16 foo = GetEqualEasyChatPairIndex(buffer2, src, r3); + if (foo < 0) + { + *(dst++) = *src; + r3++; + } + else + { + foo_of_buffer2 = (struct EasyChatPair *)((u32)buffer2 + (foo * 8)); //required to do this to reverse the order of register operands in add ASM statement + if (foo_of_buffer2->unk0_0 < src->unk0_0) + { + *foo_of_buffer2 = *src; + } + } + src++; + } + } + sub_8122804(buffer2, r3, 2); + src = buffer2; + dst = gSaveBlock1Ptr->easyChatPairs; + for (i = 0; i < 5; i++) + *(dst++) = *(src++); + Free(buffer1); + Free(buffer2); + } + } +} + +void BufferTrendyPhraseString(void) +{ + struct EasyChatPair *s = &gSaveBlock1Ptr->easyChatPairs[gSpecialVar_0x8004]; + + ConvertEasyChatWordsToString(gStringVar1, s->words, 2, 1); +} + +void TrendyPhraseIsOld(void) +{ + u16 result = 0; + + if (gSaveBlock1Ptr->easyChatPairs[0].unk0_0 - gSaveBlock1Ptr->easyChatPairs[1].unk0_0 < 2) + { + asm("":::"r2"); //Force the compiler to store address of gSaveBlock1 in r3 instead of r2 + if (!gSaveBlock1Ptr->easyChatPairs[0].unk1_6 && gSaveBlock1Ptr->easyChatPairs[1].unk1_6) + result = 1; + } + gSpecialVar_Result = result; +} + +void GetDewfordHallPaintingNameIndex(void) +{ + gSpecialVar_Result = (gSaveBlock1Ptr->easyChatPairs[0].words[0] + gSaveBlock1Ptr->easyChatPairs[0].words[1]) & 7; +} + +static bool8 sub_8122A58(struct EasyChatPair *a, struct EasyChatPair *b, u8 c) +{ + switch (c) + { + case 0: + if (a->unk0_0 > b->unk0_0) + return 1; + if (a->unk0_0 < b->unk0_0) + return 0; + if (a->unk0_7 > b->unk0_7) + return 1; + if (a->unk0_7 < b->unk0_7) + return 0; + break; + case 1: + if (a->unk0_7 > b->unk0_7) + return 1; + if (a->unk0_7 < b->unk0_7) + return 0; + if (a->unk0_0 > b->unk0_0) + return 1; + if (a->unk0_0 < b->unk0_0) + return 0; + break; + case 2: + if (a->unk0_0 > b->unk0_0) + return 1; + if (a->unk0_0 < b->unk0_0) + return 0; + if (a->unk0_7 > b->unk0_7) + return 1; + if (a->unk0_7 < b->unk0_7) + return 0; + if (a->unk2 > b->unk2) + return 1; + if (a->unk2 < b->unk2) + return 0; + if (a->words[0] > b->words[0]) + return 1; + if (a->words[0] < b->words[0]) + return 0; + if (a->words[1] > b->words[1]) + return 1; + if (a->words[1] < b->words[1]) + return 0; + return 1; + } + return Random() & 1; +} + +static void sub_8122B28(struct EasyChatPair *s) +{ + u16 r4; + + r4 = Random() % 98; + if (r4 > 50) + { + r4 = Random() % 98; + if (r4 > 80) + r4 = Random() % 98; + } + s->unk0_7 = r4 + 30; + s->unk0_0 = (Random() % (r4 + 1)) + 30; + s->unk2 = Random(); +} + +static bool8 SB1ContainsWords(u16 *a) +{ + u16 i; + + for (i = 0; i < 5; i++) + { + if (IsEasyChatPairEqual(a, gSaveBlock1Ptr->easyChatPairs[i].words) != 0) + return TRUE; + } + return FALSE; +} + +static bool8 IsEasyChatPairEqual(u16 *words1, u16 *words2) +{ + u16 i; + + for (i = 0; i < 2; i++) + { + if (*(words1++) != *(words2++)) + return FALSE; + } + return TRUE; +} + +static s16 GetEqualEasyChatPairIndex(struct EasyChatPair*s, struct EasyChatPair *a, u16 b) +{ + s16 i; + + for (i = 0; i < b; i++) + { + if (IsEasyChatPairEqual(a->words, s->words)) + return i; + s++; + } + return -1; +} diff --git a/src/mail.c b/src/mail.c index ac263ac67..85ba86974 100644 --- a/src/mail.c +++ b/src/mail.c @@ -403,11 +403,11 @@ static bool8 MailReadBuildGraphics(void) switch (sMailRead->animsActive) { case 1: - sub_80D2F68(icon); + LoadMonIconPalette(icon); sMailRead->monIconSprite = sub_80D2D78(icon, SpriteCallbackDummy, 0x60, 0x80, 0, 0); break; case 2: - sub_80D2F68(icon); + LoadMonIconPalette(icon); sMailRead->monIconSprite = sub_80D2D78(icon, SpriteCallbackDummy, 0x28, 0x80, 0, 0); break; } @@ -540,7 +540,7 @@ static void CB2_ExitMailReadFreeVars(void) { case 1: case 2: - sub_80D2FF0(sub_80D2E84(sMailRead->mail->species)); + FreeMonIconPalette(sub_80D2E84(sMailRead->mail->species)); sub_80D2EF8(&gSprites[sMailRead->monIconSprite]); } memset(sMailRead, 0, sizeof(*sMailRead)); diff --git a/src/naming_screen.c b/src/naming_screen.c index be306c765..0e350aa35 100644 --- a/src/naming_screen.c +++ b/src/naming_screen.c @@ -75,7 +75,7 @@ static const u8 gSpriteImage_858BCB8[] = INCBIN_U8("graphics/naming_screen/pc_ic static const u16 gUnknown_0858BD78[] = INCBIN_U16("graphics/naming_screen/0.gbapal"); static const u16 gUnknown_0858BD98[] = INCBIN_U16("graphics/naming_screen/1.gbapal"); -static const u8 *const gUnknown_0858BDB8[] = +static const u8 *const gUnknown_0858BDB8[] = { gText_PkmnTransferredSomeonesPC, gText_PkmnTransferredLanettesPC, @@ -85,7 +85,7 @@ static const u8 *const gUnknown_0858BDB8[] = static const u8 gUnknown_0858BDC8[] = _("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!"); -static const struct BgTemplate gUnknown_0858BE00[] = +static const struct BgTemplate gUnknown_0858BE00[] = { { .bg = 0, @@ -226,10 +226,10 @@ void DoNamingScreen(u8 templateNum, u8 *destBuffer, u16 monSpecies, u16 monGende gNamingScreenData->monPersonality = monPersonality; gNamingScreenData->destBuffer = destBuffer; gNamingScreenData->returnCallback = returnCallback; - + if (templateNum == 0) StartTimer1(); - + SetMainCallback2(C2_NamingScreen); } } @@ -316,15 +316,15 @@ static void sub_80E2FA4(void) static void NamingScreen_InitBGs(void) { u8 i; - + DmaClearLarge16(3, (void *)VRAM, VRAM_SIZE, 0x1000); DmaClear32(3, (void *)OAM, OAM_SIZE); DmaClear16(3, (void *)PLTT, PLTT_SIZE); - + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0); ResetBgsAndClearDma3BusyFlags(0); InitBgsFromTemplates(0, gUnknown_0858BE00, 4); - + ChangeBgX(0, 0, 0); ChangeBgY(0, 0, 0); ChangeBgX(1, 0, 0); @@ -333,21 +333,21 @@ static void NamingScreen_InitBGs(void) ChangeBgY(2, 0, 0); ChangeBgX(3, 0, 0); ChangeBgY(3, 0, 0); - + sub_81971D0(); sub_8197200(); - + for (i = 0; i < 5; i++) gNamingScreenData->windows[i] = AddWindow(&gUnknown_0858BE10[i]); - + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON); SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2); SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0xC, 0x8)); - + SetBgTilemapBuffer(1, gNamingScreenData->tilemapBuffer1); SetBgTilemapBuffer(2, gNamingScreenData->tilemapBuffer2); SetBgTilemapBuffer(3, gNamingScreenData->tilemapBuffer3); - + FillBgTilemapBufferRect_Palette0(1, 0, 0, 0, 0x20, 0x20); FillBgTilemapBufferRect_Palette0(2, 0, 0, 0, 0x20, 0x20); FillBgTilemapBufferRect_Palette0(3, 0, 0, 0, 0x20, 0x20); @@ -511,7 +511,7 @@ static bool8 MainState_WaitFadeOutAndExit(void) static void DisplaySentToPCMessage(void) { u8 stringToDisplay = 0; - + if (!sub_813B260()) { StringCopy(gStringVar1, GetBoxNamePtr(VarGet(VAR_STORAGE_UNKNOWN))); @@ -524,10 +524,10 @@ static void DisplaySentToPCMessage(void) StringCopy(gStringVar3, GetBoxNamePtr(get_unknown_box_id())); stringToDisplay = 2; } - + if (FlagGet(FLAG_SYS_PC_LANETTE)) stringToDisplay++; - + StringExpandPlaceholders(gStringVar4, gUnknown_0858BDB8[stringToDisplay]); NewMenuHelpers_DrawDialogueFrame(0, 0); gTextFlags.flag_0 = TRUE; @@ -538,10 +538,10 @@ static void DisplaySentToPCMessage(void) static bool8 sub_80E3604(void) { RunTextPrinters(); - + if (!IsTextPrinterActive(0) && (gMain.newKeys & A_BUTTON)) gNamingScreenData->state = MAIN_STATE_BEGIN_FADE_OUT; - + return FALSE; } @@ -562,17 +562,17 @@ static bool8 MainState_WaitPageSwap(void) s16 cursorX; s16 cursorY; bool32 var3; - + if (IsPageSwapAnimNotInProgress()) { - + GetCursorPos(&cursorX, &cursorY); var3 = (cursorX == GetCurrentPageColumnCount()); - + gNamingScreenData->state = MAIN_STATE_HANDLE_INPUT; gNamingScreenData->currentPage++; gNamingScreenData->currentPage %= 3; - + if (var3) { cursorX = GetCurrentPageColumnCount(); @@ -582,7 +582,7 @@ static bool8 MainState_WaitPageSwap(void) if (cursorX >= GetCurrentPageColumnCount()) cursorX = GetCurrentPageColumnCount() - 1; } - + SetCursorPos(cursorX, cursorY); sub_80E4E5C(); SetInputState(INPUT_STATE_ENABLED); @@ -603,7 +603,7 @@ static bool8 PageSwapAnimState_1(struct Task *); static bool8 PageSwapAnimState_2(struct Task *); static bool8 PageSwapAnimState_Done(struct Task *); -static bool8 (*const sPageSwapAnimStateFuncs[])(struct Task *) = +static bool8 (*const sPageSwapAnimStateFuncs[])(struct Task *) = { PageSwapAnimState_Init, PageSwapAnimState_1, @@ -754,7 +754,7 @@ static void Task_80E39BC(u8 taskId) task->data[3] += task->data[4]; task->data[6] += task->data[4]; } - + if (task->data[3] == 16 && task->data[6] == 22) { task->data[4] = -4; @@ -893,7 +893,7 @@ static void CursorInit(void) static void SetCursorPos(s16 x, s16 y) { struct Sprite *cursorSprite = &gSprites[gNamingScreenData->cursorSpriteId]; - + if (x < gUnknown_0858BEA0[sub_80E3274()]) cursorSprite->pos1.x = gUnknown_0858BEA3[x + sub_80E3274() * 8] + 38; else @@ -909,7 +909,7 @@ static void SetCursorPos(s16 x, s16 y) static void GetCursorPos(s16 *x, s16 *y) { struct Sprite *cursorSprite = &gSprites[gNamingScreenData->cursorSpriteId]; - + *x = cursorSprite->data[0]; *y = cursorSprite->data[1]; } @@ -1133,7 +1133,7 @@ static void CreateInputTargetIcon(void) static void TaskDummy2(void) { - + } static void NamingScreen_CreatePlayerIcon(void) @@ -1160,7 +1160,7 @@ static void NamingScreen_CreateMonIcon(void) { u8 spriteId; - sub_80D2F04(); + LoadMonIconPalettes(); spriteId = CreateMonIcon(gNamingScreenData->monSpecies, SpriteCallbackDummy, 0x38, 0x28, 0, gNamingScreenData->monPersonality, 1); gSprites[spriteId].oam.priority = 3; } @@ -1331,7 +1331,7 @@ static void InputState_Disabled(struct Task *task) static void InputState_Enabled(struct Task *task) { task->tKeyboardEvent = 0; - + if (gMain.newKeys & A_BUTTON) task->tKeyboardEvent = KBEVENT_PRESSED_A; else if (gMain.newKeys & B_BUTTON) @@ -1454,7 +1454,7 @@ static void sub_80E4894(void) static void sub_80E48E8(void) { u8 buffer[0x20]; - + StringCopy(buffer, gSpeciesNames[gNamingScreenData->monSpecies]); StringAppendN(buffer, gNamingScreenData->template->title, 15); FillWindowPixelBuffer(gNamingScreenData->windows[3], 0x11); @@ -1492,10 +1492,10 @@ static void sub_80E498C(void) static void TaskDummy3(void) { - + } -static const u8 sGenderColors[2][3] = +static const u8 sGenderColors[2][3] = { {0, 9, 8}, {0, 5, 4} @@ -1505,7 +1505,7 @@ static void sub_80E49BC(void) { u8 genderSymbol[2]; bool8 isFemale = FALSE; - + StringCopy(genderSymbol, gText_MaleSymbol); if (gNamingScreenData->monGender != MON_GENDERLESS) @@ -1575,7 +1575,7 @@ static bool8 sub_80E4B54(void) sub_80E4D10(); CopyBgTilemapBufferToVram(3); PlaySE(SE_SELECT); - + if (GetPreviousTextCaretPosition() != gNamingScreenData->template->maxChars - 1) return FALSE; else @@ -1633,7 +1633,7 @@ static void sub_80E4CF8(u8 bg, const void *src) static void nullsub_10(u8 a1, u8 a2) { - + } static void sub_80E4D10(void) @@ -1643,18 +1643,18 @@ static void sub_80E4D10(void) u16 unk2; u8 maxChars = gNamingScreenData->template->maxChars; u16 unk = gNamingScreenData->inputCharBaseXPos - 0x40; - + FillWindowPixelBuffer(gNamingScreenData->windows[2], 0x11); - + for (i = 0; i < maxChars; i++) { temp[0] = gNamingScreenData->textBuffer[i]; temp[1] = gExpandedPlaceholder_Empty[0]; unk2 = (sub_80E503C(temp[0]) == 1) ? 2 : 0; - + PrintTextOnWindow(gNamingScreenData->windows[2], 1, temp, i * 8 + unk + unk2, 1, 0xFF, NULL); } - + sub_80E498C(); CopyWindowToVram(gNamingScreenData->windows[2], 2); PutWindowTilemap(gNamingScreenData->windows[2]); @@ -1674,12 +1674,12 @@ static const struct TextColorThing sUnkColorStruct = } }; -static const u8 sFillValues[3] = +static const u8 sFillValues[3] = { 0xEE, 0xDD, 0xFF }; -static const u8 *const sUnkColors[3] = +static const u8 *const sUnkColors[3] = { sUnkColorStruct.colors[1], sUnkColorStruct.colors[0], @@ -1689,18 +1689,18 @@ static const u8 *const sUnkColors[3] = static void sub_80E4DE4(u8 window, u8 a1) { u8 i; - + FillWindowPixelBuffer(window, sFillValues[a1]); - + for (i = 0; i < 4; i++) { box_print(window, 1, 0, i * 16 + 1, sUnkColors[a1], 0, gUnknown_0858C198[a1][i]); } - + PutWindowTilemap(window); } -static const u8 *const gUnknown_0858BF98[] = +static const u8 *const gUnknown_0858BF98[] = { gUnknown_08DD4620, gUnknown_08DD46E0, @@ -1714,7 +1714,7 @@ static void sub_80E4E5C(void) u8 unk3; u8 bg1Priority = GetGpuReg(REG_OFFSET_BG1CNT) & 3; u8 bg2Priority = GetGpuReg(REG_OFFSET_BG2CNT) & 3; - + if (bg1Priority > bg2Priority) { unk1 = 1; @@ -1727,7 +1727,7 @@ static void sub_80E4E5C(void) unk2 = 2; unk3 = gNamingScreenData->windows[1]; } - + sub_80E4CF8(unk1, gUnknown_0858BF98[gNamingScreenData->currentPage]); sub_80E4DE4(unk3, sub_80E3254()); nullsub_10(unk1, sub_80E3254()); @@ -1737,7 +1737,7 @@ static void sub_80E4E5C(void) static void sub_80E4EF0(void) { const u8 color[3] = { 15, 1, 2 }; - + FillWindowPixelBuffer(gNamingScreenData->windows[4], 0xFF); box_print(gNamingScreenData->windows[4], 0, 2, 1, color, 0, gText_MoveOkBack); PutWindowTilemap(gNamingScreenData->windows[4]); @@ -1787,7 +1787,7 @@ static void sub_80E501C(void) static bool8 sub_80E503C(u8 character) { u8 i; - + for (i = 0; gUnknown_0858BDC8[i] != EOS; i++) { if (character == gUnknown_0858BDC8[i]) @@ -1987,20 +1987,20 @@ static const struct SpriteFrameImage gUnknown_0858C080[] = {gSpriteImage_858BCB8, sizeof(gSpriteImage_858BCB8)}, }; -static const union AnimCmd gSpriteAnim_858C090[] = +static const union AnimCmd gSpriteAnim_858C090[] = { ANIMCMD_FRAME(0, 1), ANIMCMD_JUMP(0) }; -static const union AnimCmd gSpriteAnim_858C098[] = +static const union AnimCmd gSpriteAnim_858C098[] = { ANIMCMD_FRAME(4, 8), ANIMCMD_FRAME(8, 8), ANIMCMD_END }; -static const union AnimCmd gSpriteAnim_858C0A4[] = +static const union AnimCmd gSpriteAnim_858C0A4[] = { ANIMCMD_FRAME(0, 2), ANIMCMD_FRAME(1, 2), @@ -2023,7 +2023,7 @@ static const union AnimCmd *const gSpriteAnimTable_858C0BC[] = gSpriteAnim_858C0A4 }; -static const struct SpriteTemplate gUnknown_0858C0C0 = +static const struct SpriteTemplate gUnknown_0858C0C0 = { .tileTag = 0x0002, .paletteTag = 0x0004, @@ -2034,7 +2034,7 @@ static const struct SpriteTemplate gUnknown_0858C0C0 = .callback = sub_80E4084 }; -static const struct SpriteTemplate gUnknown_0858C0D8 = +static const struct SpriteTemplate gUnknown_0858C0D8 = { .tileTag = 0x0003, .paletteTag = 0x0001, @@ -2045,7 +2045,7 @@ static const struct SpriteTemplate gUnknown_0858C0D8 = .callback = SpriteCallbackDummy }; -static const struct SpriteTemplate gUnknown_0858C0F0 = +static const struct SpriteTemplate gUnknown_0858C0F0 = { .tileTag = 0x0004, .paletteTag = 0x0004, @@ -2056,7 +2056,7 @@ static const struct SpriteTemplate gUnknown_0858C0F0 = .callback = SpriteCallbackDummy }; -static const struct SpriteTemplate gUnknown_0858C108 = +static const struct SpriteTemplate gUnknown_0858C108 = { .tileTag = 0x0000, .paletteTag = 0x0006, @@ -2067,7 +2067,7 @@ static const struct SpriteTemplate gUnknown_0858C108 = .callback = SpriteCallbackDummy }; -static const struct SpriteTemplate gUnknown_0858C120 = +static const struct SpriteTemplate gUnknown_0858C120 = { .tileTag = 0x0001, .paletteTag = 0x0007, @@ -2078,7 +2078,7 @@ static const struct SpriteTemplate gUnknown_0858C120 = .callback = SpriteCallbackDummy }; -static const struct SpriteTemplate gUnknown_0858C138 = +static const struct SpriteTemplate gUnknown_0858C138 = { .tileTag = 0x0007, .paletteTag = 0x0005, @@ -2089,7 +2089,7 @@ static const struct SpriteTemplate gUnknown_0858C138 = .callback = sub_80E3B30 }; -static const struct SpriteTemplate sSpriteTemplate_InputArrow = +static const struct SpriteTemplate sSpriteTemplate_InputArrow = { .tileTag = 0x000A, .paletteTag = 0x0003, @@ -2100,7 +2100,7 @@ static const struct SpriteTemplate sSpriteTemplate_InputArrow = .callback = sub_80E3C20 }; -static const struct SpriteTemplate sSpriteTemplate_Underscore = +static const struct SpriteTemplate sSpriteTemplate_Underscore = { .tileTag = 0x000B, .paletteTag = 0x0003, @@ -2111,7 +2111,7 @@ static const struct SpriteTemplate sSpriteTemplate_Underscore = .callback = sub_80E3C6C }; -static const struct SpriteTemplate gUnknown_0858C180 = +static const struct SpriteTemplate gUnknown_0858C180 = { .tileTag = 0xFFFF, .paletteTag = 0x0000, @@ -2122,7 +2122,7 @@ static const struct SpriteTemplate gUnknown_0858C180 = .callback = SpriteCallbackDummy }; -static const u8* const gUnknown_0858C198[][4] = +static const u8* const gUnknown_0858C198[][4] = { { gUnknown_0862B88D, diff --git a/src/pokemon_icon.c b/src/pokemon_icon.c index 4d1cc51c5..253ab2cb4 100644 --- a/src/pokemon_icon.c +++ b/src/pokemon_icon.c @@ -1,9 +1,28 @@ #include "global.h" #include "sprite.h" +#include "mail.h" #include "graphics.h" +#include "constants/species.h" +#include "palette.h" +#include "pokemon_icon.h" #define POKE_ICON_BASE_PAL_TAG 56000 +struct MonIconSpriteTemplate +{ + const struct OamData *oam; + const u8 *image; + const union AnimCmd *const *anims; + const union AffineAnimCmd *const *affineAnims; + void (*callback)(struct Sprite *); + u16 paletteTag; +}; + +// static functions +static u8 CreateMonIconSprite(struct MonIconSpriteTemplate *, s16, s16, u8); + +// .rodata + const u8 * const gMonIconTable[] = { gMonIcon_Bulbasaur, @@ -1012,3 +1031,288 @@ const u16 sSpriteImageSizes[3][4] = 0x400, // 4×8 }, }; + +u8 CreateMonIcon(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, u32 personality, bool32 extra) +{ + u8 spriteId; + struct MonIconSpriteTemplate iconTemplate = + { + .oam = &sMonIconOamData, + .image = GetMonIconPtr(species, personality, extra), + .anims = sMonIconAnims, + .affineAnims = sMonIconAffineAnims, + .callback = callback, + .paletteTag = POKE_ICON_BASE_PAL_TAG + gMonIconPaletteIndices[species], + }; + + if (species > SPECIES_EGG) + iconTemplate.paletteTag = POKE_ICON_BASE_PAL_TAG; + + spriteId = CreateMonIconSprite(&iconTemplate, x, y, subpriority); + + UpdateMonIconFrame(&gSprites[spriteId]); + + return spriteId; +} + +u8 sub_80D2D78(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, bool32 extra) +{ + u8 spriteId; + struct MonIconSpriteTemplate iconTemplate = + { + .oam = &sMonIconOamData, + .image = NULL, + .anims = sMonIconAnims, + .affineAnims = sMonIconAffineAnims, + .callback = callback, + .paletteTag = POKE_ICON_BASE_PAL_TAG + gMonIconPaletteIndices[species], + }; + + iconTemplate.image = GetMonIconTiles(species, extra); + spriteId = CreateMonIconSprite(&iconTemplate, x, y, subpriority); + + UpdateMonIconFrame(&gSprites[spriteId]); + + return spriteId; +} + +u16 mon_icon_convert_unown_species_id(u16 species, u32 personality) +{ + u16 result; + + if (species == SPECIES_UNOWN) + { + u16 letter = GetUnownLetterByPersonality(personality); + if (letter == 0) + letter = SPECIES_UNOWN; + else + letter += (SPECIES_UNOWN_B - 1); + result = letter; + } + else + { + if (species > SPECIES_EGG) + result = 260; + else + result = species; + } + + return result; +} + +u16 GetUnownLetterByPersonality(u32 personality) +{ + if (!personality) + return 0; + return (((personality & 0x3000000) >> 18) | ((personality & 0x30000) >> 12) | ((personality & 0x300) >> 6) | (personality & 0x3)) % 0x1C; +} + +u16 sub_80D2E84(u16 species) +{ + u16 value; + + if (MailSpeciesToSpecies(species, &value) == SPECIES_UNOWN) + { + if (value == 0) + value += SPECIES_UNOWN; + else + value += (SPECIES_UNOWN_B - 1); + return value; + } + else + { + if(species > (SPECIES_UNOWN_B - 1)) + species = 260; + return mon_icon_convert_unown_species_id(species, 0); + } +} + +const u8 *GetMonIconPtr(u16 species, u32 personality, bool32 extra) +{ + return GetMonIconTiles(mon_icon_convert_unown_species_id(species, personality), extra); +} + + + +void sub_80D2EF8(struct Sprite *sprite) +{ + sub_80D328C(sprite); +} + +void LoadMonIconPalettes(void) +{ + u8 i; + for (i = 0; i < 6; i++) + LoadSpritePalette(&gMonIconPaletteTable[i]); +} + +// unused +void SafeLoadMonIconPalette(u16 species) +{ + u8 palIndex; + if (species > SPECIES_EGG) + species = 260; + palIndex = gMonIconPaletteIndices[species]; + if (IndexOfSpritePaletteTag(gMonIconPaletteTable[palIndex].tag) == 0xFF) + LoadSpritePalette(&gMonIconPaletteTable[palIndex]); +} + +void LoadMonIconPalette(u16 species) +{ + u8 palIndex = gMonIconPaletteIndices[species]; + if (IndexOfSpritePaletteTag(gMonIconPaletteTable[palIndex].tag) == 0xFF) + LoadSpritePalette(&gMonIconPaletteTable[palIndex]); +} + +void FreeMonIconPalettes(void) +{ + u8 i; + for (i = 0; i < 6; i++) + FreeSpritePaletteByTag(gMonIconPaletteTable[i].tag); +} + +// unused +void SafeFreeMonIconPalette(u16 species) +{ + u8 palIndex; + if (species > SPECIES_EGG) + species = 260; + palIndex = gMonIconPaletteIndices[species]; + FreeSpritePaletteByTag(gMonIconPaletteTable[palIndex].tag); +} + +void FreeMonIconPalette(u16 species) +{ + u8 palIndex; + palIndex = gMonIconPaletteIndices[species]; + FreeSpritePaletteByTag(gMonIconPaletteTable[palIndex].tag); +} + +void sub_80D3014(struct Sprite *sprite) +{ + UpdateMonIconFrame(sprite); +} + +const u8* GetMonIconTiles(u16 species, bool32 extra) +{ + const u8* iconSprite = gMonIconTable[species]; + if(species == SPECIES_DEOXYS && extra == TRUE) + { + iconSprite = (const u8*)(0x400 + (u32)iconSprite); //WTF? + } + return iconSprite; +} + +void sub_80D304C(u16 offset) +{ + s32 i; + const struct SpritePalette* monIconPalettePtr; + + if(offset <= 0xA0) + { + monIconPalettePtr = gMonIconPaletteTable; + for(i = 5; i >= 0 ; i--) + { + LoadPalette(monIconPalettePtr->data, offset, 0x20); + offset += 0x10; + monIconPalettePtr++; + } + } +} + +u8 sub_80D3080(u16 species) +{ + if (species > SPECIES_EGG) + species = 260; + return gMonIconPaletteIndices[species]; +} + +u8 sub_80D30A0(u16 species) +{ + return gMonIconPaletteIndices[species]; +} + +const u16* GetValidMonIconPalettePtr(u16 species) +{ + if (species > SPECIES_EGG) + species = 260; + return gMonIconPaletteTable[gMonIconPaletteIndices[species]].data; +} + +// TODO: try to find a way to avoid using asm statement +u8 UpdateMonIconFrame(struct Sprite *sprite) +{ + u8 result = 0; + + if (sprite->animDelayCounter == 0) + { + s16 frame = sprite->anims[sprite->animNum][sprite->animCmdIndex].frame.imageValue; + + switch (frame) + { + case -1: + break; + case -2: + sprite->animCmdIndex = 0; + break; + default: + RequestSpriteCopy( + // pointer arithmetic is needed to get the correct pointer to perform the sprite copy on. + // because sprite->images is a struct def, it has to be casted to (u8 *) before any + // arithmetic can be performed. + (u8 *)sprite->images + (sSpriteImageSizes[sprite->oam.shape][sprite->oam.size] * frame), + (u8 *)(OBJ_VRAM0 + sprite->oam.tileNum * TILE_SIZE_4BPP), + sSpriteImageSizes[sprite->oam.shape][sprite->oam.size]); + { + register u8 duration asm("r0") = sprite->anims[sprite->animNum][sprite->animCmdIndex].frame.duration; + sprite->animDelayCounter = duration; + } + sprite->animCmdIndex++; + result = sprite->animCmdIndex; + break; + } + } + else + { + sprite->animDelayCounter--; + } + return result; +} + +static u8 CreateMonIconSprite(struct MonIconSpriteTemplate *iconTemplate, s16 x, s16 y, u8 subpriority) +{ + u8 spriteId; + + struct SpriteFrameImage image = { NULL, sSpriteImageSizes[iconTemplate->oam->shape][iconTemplate->oam->size] }; + + struct SpriteTemplate spriteTemplate = + { + .tileTag = 0xFFFF, + .paletteTag = iconTemplate->paletteTag, + .oam = iconTemplate->oam, + .anims = iconTemplate->anims, + .images = &image, + .affineAnims = iconTemplate->affineAnims, + .callback = iconTemplate->callback, + }; + + spriteId = CreateSprite(&spriteTemplate, x, y, subpriority); + gSprites[spriteId].animPaused = TRUE; + gSprites[spriteId].animBeginning = FALSE; + gSprites[spriteId].images = (const struct SpriteFrameImage *)iconTemplate->image; + return spriteId; +} + +void sub_80D328C(struct Sprite *sprite) +{ + struct SpriteFrameImage image = { NULL, sSpriteImageSizes[sprite->oam.shape][sprite->oam.size] }; + sprite->images = ℑ + DestroySprite(sprite); +} + +void sub_80D32C8(struct Sprite *sprite, u8 animNum) +{ + sprite->animNum = animNum; + sprite->animDelayCounter = 0; + sprite->animCmdIndex = 0; +} |