From 41858fc6bd09fbc14605efd7043c9fd1f5edd802 Mon Sep 17 00:00:00 2001 From: scbroede <32247405+scbroede@users.noreply.github.com> Date: Sat, 2 May 2026 15:21:00 -0400 Subject: [PATCH] document mail (#1128) Co-authored-by: Rachel --- asm/macros/scrcmd.inc | 6 +- generated/game_records.txt | 2 +- generated/text_banks.txt | 2 +- generated/trainer_score_events.txt | 2 +- include/applications/mail.h | 54 ++ include/applications/mail_viewer.h | 18 + include/applications/party_menu/defs.h | 4 +- include/constants/heap.h | 6 +- include/constants/items.h | 2 +- include/data/scripts/scrcmd.h | 2 +- include/item.h | 12 +- include/mail.h | 79 +- include/overlay075/ov75_021D0D80.h | 10 - include/start_menu.h | 15 +- include/struct_decls/struct_0209747C_decl.h | 6 - include/struct_defs/daycare.h | 3 +- include/struct_defs/mail.h | 27 - include/struct_defs/pokemon.h | 6 +- include/struct_defs/struct_02097728.h | 21 - include/struct_defs/struct_020978D8.h | 25 - include/struct_defs/union_02028328.h | 12 - include/unk_02014A84.h | 10 +- include/unk_02014D38.h | 2 +- include/unk_0203D1B8.h | 10 +- include/unk_0209747C.h | 16 +- include/unk_02097624.h | 21 - include/unk_020998EC.h | 2 +- platinum.us/filesys.csv | 2 +- platinum.us/filesys.sha1 | 2 +- platinum.us/main.lsf | 6 +- platinum.us/sbins_shared.sha1 | 2 +- res/field/scripts/scripts_common.s | 2 +- res/graphics/mail/air_mail.NSCR | Bin 0 -> 1572 bytes res/graphics/mail/air_mail_tiles.png | Bin 0 -> 736 bytes res/graphics/mail/bloom_mail.NSCR | Bin 0 -> 1572 bytes res/graphics/mail/bloom_mail_tiles.png | Bin 0 -> 3157 bytes res/graphics/mail/brick_mail.NSCR | Bin 0 -> 1572 bytes res/graphics/mail/brick_mail_tiles.png | Bin 0 -> 769 bytes res/graphics/mail/bubble_mail.NSCR | Bin 0 -> 1572 bytes res/graphics/mail/bubble_mail_tiles.png | Bin 0 -> 831 bytes res/graphics/mail/flame_mail.NSCR | Bin 0 -> 1572 bytes res/graphics/mail/flame_mail_tiles.png | Bin 0 -> 980 bytes res/graphics/mail/grass_mail.NSCR | Bin 0 -> 1572 bytes res/graphics/mail/grass_mail_tiles.png | Bin 0 -> 3504 bytes res/graphics/mail/heart_mail.NSCR | Bin 0 -> 1572 bytes res/graphics/mail/heart_mail_tiles.png | Bin 0 -> 787 bytes res/graphics/mail/interface.NSCR | Bin 0 -> 1572 bytes res/graphics/mail/mail.order | 37 + res/graphics/mail/meson.build | 75 ++ res/graphics/mail/mosaic_mail.NSCR | Bin 0 -> 1572 bytes res/graphics/mail/mosaic_mail_tiles.png | Bin 0 -> 839 bytes res/graphics/mail/snow_mail.NSCR | Bin 0 -> 1572 bytes res/graphics/mail/snow_mail_tiles.png | Bin 0 -> 2790 bytes res/graphics/mail/space_mail.NSCR | Bin 0 -> 1572 bytes res/graphics/mail/space_mail_tiles.png | Bin 0 -> 1537 bytes res/graphics/mail/steel_mail.NSCR | Bin 0 -> 1572 bytes res/graphics/mail/steel_mail_tiles.png | Bin 0 -> 715 bytes res/graphics/mail/tunnel_mail.NSCR | Bin 0 -> 1572 bytes res/graphics/mail/tunnel_mail_tiles.png | Bin 0 -> 3215 bytes res/graphics/meson.build | 1 + res/prebuilt/graphic/mail_gra.narc | Bin 106800 -> 0 bytes res/prebuilt/graphic/meson.build | 1 - res/text/{unk_0409.json => mail.json} | 8 +- src/applications/mail.c | 374 ++++++++ src/applications/mail_viewer.c | 952 ++++++++++++++++++++ src/applications/party_menu/main.c | 4 +- src/applications/party_menu/unk_02083370.c | 4 +- src/battle/battle_system.c | 4 +- src/daycare_save.c | 3 +- src/evolution.c | 1 - src/game_records.c | 4 +- src/item.c | 12 +- src/item_use_functions.c | 8 +- src/mail.c | 259 +++--- src/meson.build | 4 +- src/overlay005/script_message.c | 4 +- src/overlay020/ov20_021D0D80.c | 1 - src/overlay056/ov56_022561C0.c | 4 +- src/overlay062/ov62_02231690.c | 2 +- src/overlay075/ov75_021D0D80.c | 944 ------------------- src/overlay090/ov90_021D0D80.c | 2 +- src/overlay104/ov104_02231F74.c | 4 +- src/pokemon.c | 1 - src/savedata/save_table.c | 2 +- src/savedata_misc.c | 2 +- src/scrcmd.c | 7 +- src/start_menu.c | 93 +- src/unk_02014A84.c | 53 +- src/unk_02014D38.c | 2 +- src/unk_020298BC.c | 2 +- src/unk_0202D05C.c | 2 +- src/unk_02030A80.c | 2 +- src/unk_02033200.c | 2 +- src/unk_0203D1B8.c | 40 +- src/unk_0205B33C.c | 4 +- src/unk_0205C22C.c | 2 +- src/unk_020722AC.c | 27 +- src/unk_0209747C.c | 20 +- src/unk_02097624.c | 383 -------- src/unk_020998EC.c | 1 - src/unk_0209ACF4.c | 9 +- src/unk_0209B344.c | 3 +- 102 files changed, 1911 insertions(+), 1847 deletions(-) create mode 100644 include/applications/mail.h create mode 100644 include/applications/mail_viewer.h delete mode 100644 include/overlay075/ov75_021D0D80.h delete mode 100644 include/struct_decls/struct_0209747C_decl.h delete mode 100644 include/struct_defs/mail.h delete mode 100644 include/struct_defs/struct_02097728.h delete mode 100644 include/struct_defs/struct_020978D8.h delete mode 100644 include/struct_defs/union_02028328.h delete mode 100644 include/unk_02097624.h create mode 100644 res/graphics/mail/air_mail.NSCR create mode 100644 res/graphics/mail/air_mail_tiles.png create mode 100644 res/graphics/mail/bloom_mail.NSCR create mode 100644 res/graphics/mail/bloom_mail_tiles.png create mode 100644 res/graphics/mail/brick_mail.NSCR create mode 100644 res/graphics/mail/brick_mail_tiles.png create mode 100644 res/graphics/mail/bubble_mail.NSCR create mode 100644 res/graphics/mail/bubble_mail_tiles.png create mode 100644 res/graphics/mail/flame_mail.NSCR create mode 100644 res/graphics/mail/flame_mail_tiles.png create mode 100644 res/graphics/mail/grass_mail.NSCR create mode 100644 res/graphics/mail/grass_mail_tiles.png create mode 100644 res/graphics/mail/heart_mail.NSCR create mode 100644 res/graphics/mail/heart_mail_tiles.png create mode 100644 res/graphics/mail/interface.NSCR create mode 100644 res/graphics/mail/mail.order create mode 100644 res/graphics/mail/meson.build create mode 100644 res/graphics/mail/mosaic_mail.NSCR create mode 100644 res/graphics/mail/mosaic_mail_tiles.png create mode 100644 res/graphics/mail/snow_mail.NSCR create mode 100644 res/graphics/mail/snow_mail_tiles.png create mode 100644 res/graphics/mail/space_mail.NSCR create mode 100644 res/graphics/mail/space_mail_tiles.png create mode 100644 res/graphics/mail/steel_mail.NSCR create mode 100644 res/graphics/mail/steel_mail_tiles.png create mode 100644 res/graphics/mail/tunnel_mail.NSCR create mode 100644 res/graphics/mail/tunnel_mail_tiles.png delete mode 100644 res/prebuilt/graphic/mail_gra.narc rename res/text/{unk_0409.json => mail.json} (63%) create mode 100644 src/applications/mail.c create mode 100644 src/applications/mail_viewer.c delete mode 100644 src/overlay075/ov75_021D0D80.c delete mode 100644 src/unk_02097624.c diff --git a/asm/macros/scrcmd.inc b/asm/macros/scrcmd.inc index ace0b42186..58d9cfb0ab 100644 --- a/asm/macros/scrcmd.inc +++ b/asm/macros/scrcmd.inc @@ -2508,9 +2508,9 @@ .short SCRCMD_1B3 .endm - .macro ScrCmd_1B4 arg0 - .short SCRCMD_1B4 - .short \arg0 + .macro CountMailInMailbox destVar + .short SCRCMD_COUNTMAILINMAILBOX + .short \destVar .endm .macro StartRankingsMachine machineID diff --git a/generated/game_records.txt b/generated/game_records.txt index 5131061978..960256c3c4 100644 --- a/generated/game_records.txt +++ b/generated/game_records.txt @@ -43,7 +43,7 @@ RECORD_FAINTED_IN_BATTLE RECORD_UNK_042 RECORD_UNK_043 RECORD_UNK_044 -RECORD_UNK_045 +RECORD_TIMES_MAIL_WRITTEN RECORD_UNK_046 RECORD_SPHERES_BURIED RECORD_WATCHED_TV diff --git a/generated/text_banks.txt b/generated/text_banks.txt index f5412df16b..c7cdf8a5cd 100644 --- a/generated/text_banks.txt +++ b/generated/text_banks.txt @@ -407,7 +407,7 @@ TEXT_BANK_ACUITY_LAKEFRONT TEXT_BANK_SAVE_CORRUPTED TEXT_BANK_UNK_0407 TEXT_BANK_MAILBOX -TEXT_BANK_UNK_0409 +TEXT_BANK_MAIL TEXT_BANK_UNK_0410 TEXT_BANK_UNK_0411 TEXT_BANK_SPECIES_NAME diff --git a/generated/trainer_score_events.txt b/generated/trainer_score_events.txt index 6d52dc63c1..d53450cdf5 100644 --- a/generated/trainer_score_events.txt +++ b/generated/trainer_score_events.txt @@ -1,6 +1,6 @@ TRAINER_SCORE_EVENT_BERRY_HARVESTED TRAINER_SCORE_EVENT_HONEY_USED -TRAINER_SCORE_EVENT_UNK_02 +TRAINER_SCORE_EVENT_MAIL_WRITTEN TRAINER_SCORE_EVENT_TV_INTERVIEW_GIVEN TRAINER_SCORE_EVENT_SIGNED_TRAINER_CARD TRAINER_SCORE_EVENT_UNK_05 diff --git a/include/applications/mail.h b/include/applications/mail.h new file mode 100644 index 0000000000..1b60e64974 --- /dev/null +++ b/include/applications/mail.h @@ -0,0 +1,54 @@ +#ifndef POKEPLATINUM_APPLICATIONS_MAIL_H +#define POKEPLATINUM_APPLICATIONS_MAIL_H + +#include "struct_defs/sentence.h" + +#include "game_options.h" +#include "mail.h" +#include "pokemon.h" +#include "savedata.h" +#include "string_gf.h" + +typedef struct MailAppArgs { + u16 writeMode; + u8 padding[2]; + BOOL mailWritten; + enum MailContext contextUnused; + u16 mailboxSlotUnused; + u8 partySlotUnused; + u8 mailType; + SaveData *saveData; + Mail *mail; + Mailbox *mailbox; +} MailAppArgs; + +typedef struct MailViewerAppArgs { + union { + u16 writeMode; + u16 result; + }; + u8 sentenceIndex; + u8 horizontalSelectionIndex; + Options *options; + u32 trainerID; + u8 padding; + u8 language; + u8 gameVersion; + u8 mailType; + String *trainerName; + MailIconData iconData[MAIL_MAX_ICONS]; + Sentence sentences[MAIL_MAX_SENTENCES]; +} MailViewerAppArgs; + +MailAppArgs *MailAppArgs_New_Write(SaveData *saveData, enum MailContext context, u8 partySlot, u8 mailType, enum HeapID heapID); +MailAppArgs *MailAppArgs_New_ReadFromMailbox(SaveData *saveData, enum MailContext context, u16 mailboxSlot, enum HeapID heapID); +MailAppArgs *MailAppArgs_New_ReadHeld(SaveData *saveData, Pokemon *mon, enum HeapID heapID); +MailAppArgs *MailAppArgs_New_Check(SaveData *saveData, u8 mailType, enum HeapID heapID); +BOOL MailApp_WasMailWritten(MailAppArgs *args); +BOOL MailApp_CopyWrittenMailToMailboxSlot(MailAppArgs *args, enum MailContext context, u8 slot); +BOOL MailApp_AddWrittenMailToMon(MailAppArgs *args, Pokemon *mon); +void MailAppArgs_Free(MailAppArgs *args); +int Mail_TransferFromMonToMailbox(Mailbox *mailbox, Pokemon *mon, enum HeapID heapID); +int Mail_TransferFromMailboxToMon(Mailbox *mailbox, u16 slot, Pokemon *mon, enum HeapID heapID); + +#endif // POKEPLATINUM_APPLICATIONS_MAIL_H diff --git a/include/applications/mail_viewer.h b/include/applications/mail_viewer.h new file mode 100644 index 0000000000..27007d3d61 --- /dev/null +++ b/include/applications/mail_viewer.h @@ -0,0 +1,18 @@ +#ifndef POKEPLATINUM_APPLICATIONS_MAIL_VIEWER_H +#define POKEPLATINUM_APPLICATIONS_MAIL_VIEWER_H + +#include "overlay_manager.h" + +enum MailViewerResult { + MAIL_VIEWER_RESULT_EDIT_SENTENCE_1 = 0, + MAIL_VIEWER_RESULT_EDIT_SENTENCE_2, + MAIL_VIEWER_RESULT_EDIT_SENTENCE_3, + MAIL_VIEWER_RESULT_CONFIRM, + MAIL_VIEWER_RESULT_CANCEL = 0xFFFF, +}; + +BOOL MailViewer_Init(ApplicationManager *appMan, int *state); +BOOL MailViewer_Main(ApplicationManager *appMan, int *state); +BOOL MailViewer_Exit(ApplicationManager *appMan, int *state); + +#endif // POKEPLATINUM_APPLICATIONS_MAIL_VIEWER_H diff --git a/include/applications/party_menu/defs.h b/include/applications/party_menu/defs.h index 65b022f7a4..bec5dd6ac0 100644 --- a/include/applications/party_menu/defs.h +++ b/include/applications/party_menu/defs.h @@ -5,7 +5,6 @@ #include "constants/pokemon.h" #include "struct_defs/function_ptr_pair.h" -#include "struct_defs/mail.h" #include "struct_defs/tv.h" #include "field/field_system_decl.h" @@ -19,6 +18,7 @@ #include "g3d_pipeline.h" #include "game_options.h" #include "grid_menu_cursor_position.h" +#include "mail.h" #include "menu.h" #include "message.h" #include "particle_system.h" @@ -77,7 +77,7 @@ enum PartyMenuExitCodes { PARTY_MENU_EXIT_CODE_GIVE_ITEM, PARTY_MENU_EXIT_CODE_OVERWRITE_MOVE_TM_HM, PARTY_MENU_EXIT_CODE_OVERWRITE_MOVE_LEVEL_UP, - PARTY_MENU_EXIT_CODE_MAIL, + PARTY_MENU_EXIT_CODE_WRITE_MAIL, PARTY_MENU_EXIT_CODE_READ_MAIL, PARTY_MENU_EXIT_CODE_EVOLVE_BY_ITEM, PARTY_MENU_EXIT_CODE_EVOLVE_BY_LEVEL, diff --git a/include/constants/heap.h b/include/constants/heap.h index ecc2ae05fb..ef9f4f39fb 100644 --- a/include/constants/heap.h +++ b/include/constants/heap.h @@ -42,8 +42,8 @@ enum HeapID { HEAP_ID_POKEDEX, HEAP_ID_OPTIONS_MENU, HEAP_ID_DRAWING, - HEAP_ID_40, - HEAP_ID_41, + HEAP_ID_MAIL, + HEAP_ID_MAIL_VIEWER, HEAP_ID_JOURNAL, HEAP_ID_43, HEAP_ID_POFFIN_CASE, @@ -160,6 +160,8 @@ enum HeapSize { HEAP_SIZE_DISTORTION_WORLD_WARP = 0x50000, HEAP_SIZE_UNDERGROUND = 0xE800, HEAP_SIZE_DRAWING = 0x40000, + HEAP_SIZE_MAIL = 0x1000, + HEAP_SIZE_MAIL_VIEWER = 0x20000, HEAP_SIZE_BOAT_CUTSCENE = 0x20000, HEAP_SIZE_EVOLUTION = 0x30000, HEAP_SIZE_GAME_START = 0x20000, diff --git a/include/constants/items.h b/include/constants/items.h index 16c611738d..e39ac5e5a5 100644 --- a/include/constants/items.h +++ b/include/constants/items.h @@ -51,7 +51,7 @@ #define FIRST_MAIL_IDX ITEM_GRASS_MAIL #define LAST_MAIL_IDX ITEM_BRICK_MAIL -#define NUM_MAILS (LAST_MAIL_IDX - FIRST_MAIL_IDX + 1) +#define NUM_MAIL_TYPES (LAST_MAIL_IDX - FIRST_MAIL_IDX + 1) #define MAIL_ID(__name) (ITEM_##__name##_MAIL - FIRST_MAIL_IDX) #define FIRST_BERRY_IDX ITEM_CHERI_BERRY diff --git a/include/data/scripts/scrcmd.h b/include/data/scripts/scrcmd.h index e85a95fcb8..fd301551d3 100644 --- a/include/data/scripts/scrcmd.h +++ b/include/data/scripts/scrcmd.h @@ -441,7 +441,7 @@ ScriptCommand(SCRCMD_STOREPARTYMONINTODAYCARE, ScrCm ScriptCommand(SCRCMD_SHOWOBJECT, ScrCmd_ShowObject) ScriptCommand(SCRCMD_HIDEOBJECT, ScrCmd_HideObject) ScriptCommand(SCRCMD_1B3, ScrCmd_1B3) -ScriptCommand(SCRCMD_1B4, ScrCmd_1B4) +ScriptCommand(SCRCMD_COUNTMAILINMAILBOX, ScrCmd_CountMailInMailbox) ScriptCommand(SCRCMD_STARTRANKINGSMACHINE, ScrCmd_StartRankingsMachine) ScriptCommand(SCRCMD_GETTIMEOFDAY, ScrCmd_GetTimeOfDay) ScriptCommand(SCRCMD_GETRANDOM, ScrCmd_GetRandom) diff --git a/include/item.h b/include/item.h index 4af295b52c..bfc36f451c 100644 --- a/include/item.h +++ b/include/item.h @@ -275,20 +275,20 @@ u8 Item_TMHMNumber(u16 item); u8 Item_IsMail(u16 item); /** - * @brief Get the mail number for a given item. + * @brief Get the mail type for a given item. * * @param item - * @return The mail number for the item, or ITEM_NONE if the item is not mail. + * @return The mail type for the item, or ITEM_NONE if the item is not mail. */ -u8 Item_MailNumber(u16 item); +u8 Item_GetMailType(u16 item); /** - * @brief Get the item for a given mail number. + * @brief Get the item for a given mail type. * * @param mail - * @return The item for the mail number, or ITEM_NONE if none exists. + * @return The item for the mail type, or ITEM_NONE if none exists. */ -u16 Item_ForMailNumber(u8 mail); +u16 Item_ForMailType(u8 mailType); /** * @brief Check if a given item is a berry. diff --git a/include/mail.h b/include/mail.h index e8fbf42b61..52e86f0062 100644 --- a/include/mail.h +++ b/include/mail.h @@ -1,34 +1,83 @@ #ifndef POKEPLATINUM_MAIL_H #define POKEPLATINUM_MAIL_H -#include "struct_defs/mail.h" +#include "constants/string.h" +#include "struct_defs/sentence.h" + +#include "charcode.h" #include "savedata.h" -void Mail_Init(Mail *mail); -BOOL Mail_IsEmpty(Mail *mail); +#define MAIL_TYPE_NONE 0xFFFF + +#define MAIL_MON_ICON_NONE 0xFFFF + +#define MAIL_MAX_SENTENCES 3 +#define MAIL_MAX_ICONS 3 + +#define MAILBOX_SIZE 20 + +enum MailContext { + MAIL_CONTEXT_MAILBOX = 0, + MAIL_CONTEXT_1_UNUSED, + MAIL_CONTEXT_WRITE, + MAIL_CONTEXT_CHECK, +}; + +enum MailIconDataType { + ICON_DATA_SPRITE_INDEX = 0, + ICON_DATA_PLTT_INDEX, + ICON_DATA_VALUE, +}; + +typedef union MailIconData { + struct { + u16 spriteIndex : 12; + u16 palIndex : 4; + } asStruct; + u16 asValue; +} MailIconData; + +typedef struct Mail { + u32 trainerID; + u8 trainerGender; + u8 language; + u8 gameVersion; + u8 mailType; + charcode_t trainerName[TRAINER_NAME_LEN + 1]; + MailIconData iconData[MAIL_MAX_ICONS]; + u16 platExclusiveFormIcons; + Sentence sentences[MAIL_MAX_SENTENCES]; +} Mail; + +typedef struct Mailbox { + Mail mail[MAILBOX_SIZE]; +} Mailbox; + +void Mail_Reset(Mail *mail); +BOOL Mail_IsValid(Mail *mail); Mail *Mail_New(enum HeapID heapID); void Mail_Copy(Mail *src, Mail *dest); -void sub_020281AC(Mail *mail, u8 mailType, u8 param2, SaveData *saveData); +void Mail_SetTrainerAndIconData(Mail *mail, u8 mailType, u8 selectedPartySlot, SaveData *saveData); u32 Mail_GetTrainerID(const Mail *mail); -u16 *Mail_GetTrainerName(Mail *mail); +charcode_t *Mail_GetTrainerName(Mail *mail); u8 Mail_GetTrainerGender(const Mail *mail); u8 Mail_GetMailType(const Mail *mail); void Mail_SetMailType(Mail *mail, const u8 mailType); u8 Mail_GetLanguage(const Mail *mail); u8 Mail_GetGameVersion(const Mail *mail); -u16 sub_02028328(const Mail *param0, u8 param1, u8 param2, u16 param3); -u16 sub_02028408(const Mail *param0); -Sentence *sub_0202840C(Mail *param0, u8 param1); -void sub_0202841C(Mail *param0, Sentence *param1, u8 param2); +u16 Mail_GetIconData(const Mail *mail, u8 index, enum MailIconDataType type, u16 platExclusiveFormIcons); +u16 Mail_GetPlatExclusiveFormIcons(const Mail *mail); +Sentence *Mail_GetSentence(Mail *mail, u8 index); +void Mail_SetSentence(Mail *mail, Sentence *sentence, u8 index); Mailbox *SaveData_GetMailbox(SaveData *saveData); int Mailbox_SaveSize(void); void Mailbox_Init(Mailbox *mailbox); -int Mail_GetEmptySlotInArray(Mailbox *mailbox, int param1); -void sub_02028470(Mailbox *mailbox, int param1, int slot); -void Mailbox_CopyMailToSlot(Mailbox *mailbox, int param1, int slot, Mail *src); -int sub_02028494(Mailbox *mailbox, int param1); -Mail *sub_020284A8(Mailbox *mailbox, int param1, int slot, enum HeapID heapID); -void sub_020284CC(Mailbox *mailbox, int param1, int param2, Mail *param3); +int Mail_GetEmptyMailSlot(Mailbox *mailbox, enum MailContext context); +void Mailbox_ClearMailAtSlot(Mailbox *mailbox, enum MailContext context, int slot); +void Mailbox_CopyMailToSlot(Mailbox *mailbox, enum MailContext context, int slot, Mail *src); +int Mailbox_CountMail(Mailbox *mailbox, enum MailContext context); +Mail *Mailbox_CopyMailAtSlot(Mailbox *mailbox, enum MailContext context, int slot, enum HeapID heapID); +void Mailbox_GetMailAtSlot(Mailbox *mailbox, enum MailContext context, int slot, Mail *out); #endif // POKEPLATINUM_MAIL_H diff --git a/include/overlay075/ov75_021D0D80.h b/include/overlay075/ov75_021D0D80.h deleted file mode 100644 index e201ebc06d..0000000000 --- a/include/overlay075/ov75_021D0D80.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef POKEPLATINUM_OV75_021D0D80_H -#define POKEPLATINUM_OV75_021D0D80_H - -#include "overlay_manager.h" - -int ov75_021D0D80(ApplicationManager *appMan, int *param1); -int ov75_021D0DF8(ApplicationManager *appMan, int *param1); -int ov75_021D0E10(ApplicationManager *appMan, int *param1); - -#endif // POKEPLATINUM_OV75_021D0D80_H diff --git a/include/start_menu.h b/include/start_menu.h index 159b3bd76a..f7d9fba499 100644 --- a/include/start_menu.h +++ b/include/start_menu.h @@ -1,5 +1,5 @@ -#ifndef POKEPLATINUM_UNK_0203A9C8_H -#define POKEPLATINUM_UNK_0203A9C8_H +#ifndef POKEPLATINUM_START_MENU_H +#define POKEPLATINUM_START_MENU_H #include "field/field_system_decl.h" #include "overlay005/sprite_resource_manager.h" @@ -53,6 +53,13 @@ enum StartMenuState { START_MENU_STATE_SAVED, }; +enum MailUsageType { + MAIL_GIVE_FROM_PARTY_MENU = 0, + MAIL_GIVE_FROM_BAG, + MAIL_READ_FROM_PARTY_MENU, + MAIL_READ_FROM_BAG, +}; + extern const u8 gAllSummaryScreenPages[]; BOOL FieldSystem_IsInValidLocation(FieldSystem *fieldSystem); @@ -65,10 +72,10 @@ BOOL StartMenu_ExitPartyMenu(FieldTask *fieldTask); BOOL StartMenu_ExitTownMap(FieldTask *fieldTask); BOOL StartMenu_FlyDestinationSelected(FieldTask *fieldTask); BOOL StartMenu_ExitJournal(FieldTask *fieldTask); -void *sub_0203C540(u16 param0, u8 param1, u8 param2); +void *StartMenu_BuildMailData(u16 itemID, u8 usageType, u8 partySlot); BOOL StartMenu_ExitMail(FieldTask *fieldTask); BOOL StartMenu_ExitPoffinCase(FieldTask *fieldTask); BOOL StartMenu_ExitPalPad(FieldTask *fieldTask); BOOL StartMenu_ExitVsRecorder(FieldTask *fieldTask); -#endif // POKEPLATINUM_UNK_0203A9C8_H +#endif // POKEPLATINUM_START_MENU_H diff --git a/include/struct_decls/struct_0209747C_decl.h b/include/struct_decls/struct_0209747C_decl.h deleted file mode 100644 index 6dd3f1ebb6..0000000000 --- a/include/struct_decls/struct_0209747C_decl.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef POKEPLATINUM_STRUCT_0209747C_DECL_H -#define POKEPLATINUM_STRUCT_0209747C_DECL_H - -typedef struct UnkStruct_0209747C_t UnkStruct_0209747C; - -#endif // POKEPLATINUM_STRUCT_0209747C_DECL_H diff --git a/include/struct_defs/daycare.h b/include/struct_defs/daycare.h index 8c248c0d7b..9a0c47656e 100644 --- a/include/struct_defs/daycare.h +++ b/include/struct_defs/daycare.h @@ -3,9 +3,10 @@ #include "constants/daycare.h" -#include "struct_defs/mail.h" #include "struct_defs/pokemon.h" +#include "mail.h" + typedef struct DaycareMail { Mail mail; u16 otName[TRAINER_NAME_LEN + 1]; diff --git a/include/struct_defs/mail.h b/include/struct_defs/mail.h deleted file mode 100644 index e0b7069ef6..0000000000 --- a/include/struct_defs/mail.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef POKEPLATINUM_STRUCT_MAIL_H -#define POKEPLATINUM_STRUCT_MAIL_H - -#include "constants/string.h" - -#include "struct_defs/sentence.h" -#include "struct_defs/union_02028328.h" - -#define MAILBOX_SIZE 20 - -typedef struct Mail { - u32 trainerID; - u8 trainerGender; - u8 language; - u8 gameVersion; - u8 mailType; - u16 trainerName[TRAINER_NAME_LEN + 1]; - UnkUnion_02028328 unk_18[3]; - u16 unk_1E; - Sentence unk_20[3]; -} Mail; - -typedef struct Mailbox { - Mail mail[MAILBOX_SIZE]; -} Mailbox; - -#endif // POKEPLATINUM_STRUCT_MAIL_H diff --git a/include/struct_defs/pokemon.h b/include/struct_defs/pokemon.h index 92985cdc92..e7c2c204a3 100644 --- a/include/struct_defs/pokemon.h +++ b/include/struct_defs/pokemon.h @@ -4,7 +4,10 @@ #include "constants/moves.h" #include "constants/string.h" +#include "struct_defs/seal_case.h" + #include "charcode.h" +#include "mail.h" // clang-format off /** @@ -125,9 +128,6 @@ typedef struct BoxPokemon { } BoxPokemon; // clang-format on -#include "struct_defs/mail.h" -#include "struct_defs/seal_case.h" - /** * @brief Party Pokemon data structure * This is used to store stats for a pokemon while it is in the players party. diff --git a/include/struct_defs/struct_02097728.h b/include/struct_defs/struct_02097728.h deleted file mode 100644 index 27100eb79e..0000000000 --- a/include/struct_defs/struct_02097728.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef POKEPLATINUM_STRUCT_02097728_H -#define POKEPLATINUM_STRUCT_02097728_H - -#include "struct_defs/mail.h" - -#include "savedata.h" - -typedef struct { - u16 unk_00; - u16 unk_02; - int unk_04; - int unk_08; - u16 unk_0C; - u8 unk_0E; - u8 unk_0F; - SaveData *saveData; - Mail *unk_14; - Mailbox *mailbox; -} UnkStruct_02097728; - -#endif // POKEPLATINUM_STRUCT_02097728_H diff --git a/include/struct_defs/struct_020978D8.h b/include/struct_defs/struct_020978D8.h deleted file mode 100644 index d8f133ff90..0000000000 --- a/include/struct_defs/struct_020978D8.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef POKEPLATINUM_STRUCT_020978D8_H -#define POKEPLATINUM_STRUCT_020978D8_H - -#include "struct_defs/sentence.h" -#include "struct_defs/union_02028328.h" - -#include "game_options.h" -#include "string_gf.h" - -typedef struct { - u16 unk_00; - u8 unk_02; - u8 unk_03; - Options *options; - u32 unk_08; - u8 unk_0C; - u8 language; - u8 gameVersion; - u8 mailType; - String *unk_10; - UnkUnion_02028328 unk_14[3]; - Sentence unk_1A[3]; -} UnkStruct_020978D8; - -#endif // POKEPLATINUM_STRUCT_020978D8_H diff --git a/include/struct_defs/union_02028328.h b/include/struct_defs/union_02028328.h deleted file mode 100644 index 7268453f53..0000000000 --- a/include/struct_defs/union_02028328.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef POKEPLATINUM_UNION_02028328_H -#define POKEPLATINUM_UNION_02028328_H - -typedef union { - struct { - u16 val1_0 : 12; - u16 val1_12 : 4; - }; - u16 val2; -} UnkUnion_02028328; - -#endif // POKEPLATINUM_UNION_02028328_H diff --git a/include/unk_02014A84.h b/include/unk_02014A84.h index fe3923b24a..eeb769aaf3 100644 --- a/include/unk_02014A84.h +++ b/include/unk_02014A84.h @@ -7,19 +7,19 @@ #include "string_gf.h" -void sub_02014A84(Sentence *sentence); -void sub_02014A9C(Sentence *sentence, u32 param1); +void Sentence_Init(Sentence *sentence); +void Sentence_InitWithType(Sentence *sentence, u32 type); void sub_02014AB4(Sentence *sentence); void sub_02014AC4(Sentence *sentence, int param1); -String *sub_02014B34(const Sentence *sentence, enum HeapID heapID); +String *Sentence_AsString(const Sentence *sentence, enum HeapID heapID); String *sub_02014BA0(const Sentence *sentence, u32 param1); -BOOL sub_02014BBC(const Sentence *sentence); +BOOL Sentence_IsValid(const Sentence *sentence); BOOL sub_02014BD0(const Sentence *sentence); u16 Sentence_GetWord(const Sentence *sentence, int slot); u32 sub_02014C80(const Sentence *sentence); u32 sub_02014C84(const Sentence *sentence); BOOL sub_02014C88(const Sentence *param0, const Sentence *param1); -void sub_02014CC0(Sentence *param0, const Sentence *param1); +void Sentence_Set(Sentence *param0, const Sentence *param1); u32 sub_02014CD4(u32 param0); void sub_02014CE0(Sentence *sentence, u32 param1, u32 param2); void Sentence_SetWord(Sentence *sentence, u32 index, u16 word); diff --git a/include/unk_02014D38.h b/include/unk_02014D38.h index 584c585b35..df8924c10d 100644 --- a/include/unk_02014D38.h +++ b/include/unk_02014D38.h @@ -15,7 +15,7 @@ void sub_02014DB8(u16 param0, String *param1); u16 sub_02014DFC(u32 param0, u32 param1); BOOL sub_02014E4C(u16 param0, u32 *param1, u32 *param2); u32 Sentence_SaveSize(void); -void Sentence_Init(void *param0); +void SentenceSaveData_Init(void *param0); UnkStruct_02014EC4 *sub_02014EC4(SaveData *saveData); BOOL sub_02014ED8(const UnkStruct_02014EC4 *param0, u32 param1); u32 sub_02014EE4(UnkStruct_02014EC4 *param0); diff --git a/include/unk_0203D1B8.h b/include/unk_0203D1B8.h index 5da19d7850..346b9bb871 100644 --- a/include/unk_0203D1B8.h +++ b/include/unk_0203D1B8.h @@ -5,13 +5,12 @@ #include "generated/items.h" #include "generated/pokemon_contest_types.h" -#include "struct_decls/struct_0209747C_decl.h" #include "struct_defs/choose_starter_data.h" #include "struct_defs/clear_game_player_info.h" #include "struct_defs/hall_of_fame_display_data.h" #include "struct_defs/struct_0203E348.h" -#include "struct_defs/struct_02097728.h" +#include "applications/mail.h" #include "applications/naming_screen.h" #include "applications/party_menu/defs.h" #include "applications/pc_boxes/pokemon_storage_session.h" @@ -31,6 +30,7 @@ #include "pokemon.h" #include "savedata.h" #include "trainer_case.h" +#include "unk_0209747C.h" void FieldSystem_StartBattleProcess(FieldSystem *fieldSystem, FieldBattleDTO *dto); void sub_0203D1E4(FieldSystem *fieldSystem, BagContext *param1); @@ -63,9 +63,9 @@ void sub_0203D874(FieldSystem *fieldSystem, UnkStruct_0209747C *param1); void FieldSystem_OpenTownMap(FieldSystem *fieldSystem, TownMapContext *townMapCtx); void *FieldSystem_OpenTownMapItem(FieldSystem *fieldSystem); void *FieldSystem_OpenOptionsMenu(FieldSystem *fieldSystem); -UnkStruct_02097728 *sub_0203D920(FieldSystem *fieldSystem, int param1, u8 param2, u8 mailType, int unusedHeapID); -UnkStruct_02097728 *sub_0203D94C(FieldSystem *fieldSystem, int param1, u8 param2, enum HeapID heapID); -UnkStruct_02097728 *sub_0203D984(FieldSystem *fieldSystem, Pokemon *param1, enum HeapID heapID); +MailAppArgs *FieldSystem_LaunchMailApp_Write(FieldSystem *fieldSystem, enum MailContext context, u8 partySlot, u8 mailType, int unusedHeapID); +MailAppArgs *FieldSystem_LaunchMailApp_Read(FieldSystem *fieldSystem, enum MailContext context, u8 mailType, enum HeapID heapID); +MailAppArgs *FieldSystem_LaunchMailApp_ReadHeld(FieldSystem *fieldSystem, Pokemon *param1, enum HeapID heapID); PoffinCaseAppData *FieldSystem_LaunchPoffinCaseApp(FieldSystem *fieldSystem, enum HeapID heapID); void sub_0203D9D8(FieldSystem *fieldSystem, UnkStruct_ov90_021D0D80 *param1); void sub_0203DAC0(FieldTask *param0, u16 *param1, SaveData *saveData, u16 param3, u16 param4); diff --git a/include/unk_0209747C.h b/include/unk_0209747C.h index 234f12d84e..b44b0911a5 100644 --- a/include/unk_0209747C.h +++ b/include/unk_0209747C.h @@ -2,12 +2,26 @@ #define POKEPLATINUM_UNK_0209747C_H #include "struct_decls/struct_02014EC4_decl.h" -#include "struct_decls/struct_0209747C_decl.h" #include "struct_defs/sentence.h" #include "pokedex.h" #include "savedata.h" +typedef struct UnkStruct_0209747C { + u8 unk_00; + u8 unk_01; + u8 unk_02; + u8 unk_03; + u8 unk_04; + u8 unk_05; + int unk_08; + const Pokedex *unk_0C; + const UnkStruct_02014EC4 *unk_10; + Sentence unk_14; + u16 unk_1C[2]; + u16 unk_20[2]; +} UnkStruct_0209747C; + UnkStruct_0209747C *sub_0209747C(u32 param0, u32 param1, SaveData *saveData, enum HeapID heapID); void sub_020974EC(UnkStruct_0209747C *param0); void sub_020974F4(UnkStruct_0209747C *param0, u16 param1); diff --git a/include/unk_02097624.h b/include/unk_02097624.h deleted file mode 100644 index 44033f74a7..0000000000 --- a/include/unk_02097624.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef POKEPLATINUM_UNK_02097624_H -#define POKEPLATINUM_UNK_02097624_H - -#include "struct_defs/mail.h" -#include "struct_defs/struct_02097728.h" - -#include "pokemon.h" -#include "savedata.h" - -UnkStruct_02097728 *sub_02097624(SaveData *saveData, int param1, u8 param2, u8 param3, enum HeapID heapID); -UnkStruct_02097728 *sub_0209767C(SaveData *saveData, int param1, u16 param2, enum HeapID heapID); -UnkStruct_02097728 *sub_020976BC(SaveData *saveData, Pokemon *param1, enum HeapID heapID); -UnkStruct_02097728 *sub_020976F4(SaveData *saveData, u8 param1, enum HeapID heapID); -BOOL sub_02097728(UnkStruct_02097728 *param0); -int sub_0209772C(UnkStruct_02097728 *param0, int param1, u8 param2); -int sub_02097750(UnkStruct_02097728 *param0, Pokemon *param1); -void sub_02097770(UnkStruct_02097728 *param0); -int sub_02097788(Mailbox *mailbox, Pokemon *mon, enum HeapID heapID); -int sub_020977E4(Mailbox *mailbox, u16 param1, Pokemon *param2, enum HeapID heapID); - -#endif // POKEPLATINUM_UNK_02097624_H diff --git a/include/unk_020998EC.h b/include/unk_020998EC.h index 9528f8e2a9..824cd9111b 100644 --- a/include/unk_020998EC.h +++ b/include/unk_020998EC.h @@ -1,10 +1,10 @@ #ifndef POKEPLATINUM_UNK_020998EC_H #define POKEPLATINUM_UNK_020998EC_H -#include "struct_decls/struct_0209747C_decl.h" #include "struct_decls/struct_020998EC_decl.h" #include "string_gf.h" +#include "unk_0209747C.h" UnkStruct_020998EC *sub_020998EC(u32 heapID, const UnkStruct_0209747C *param1); void sub_0209992C(UnkStruct_020998EC *param0); diff --git a/platinum.us/filesys.csv b/platinum.us/filesys.csv index ad8c6c2bb2..02b0d67188 100644 --- a/platinum.us/filesys.csv +++ b/platinum.us/filesys.csv @@ -208,7 +208,7 @@ res/prebuilt/graphic/hiden_effect.narc,/graphic/hiden_effect.narc res/prebuilt/graphic/imageclip.narc,/graphic/imageclip.narc res/prebuilt/graphic/library_tv.narc,/graphic/library_tv.narc res/prebuilt/graphic/lobby_news.narc,/graphic/lobby_news.narc -res/prebuilt/graphic/mail_gra.narc,/graphic/mail_gra.narc +res/graphics/mail/mail.narc,/graphic/mail_gra.narc res/graphics/start_menu/start_menu.narc,/graphic/menu_gra.narc res/graphics/signature_interface/signature_interface.narc,/graphic/mysign.narc res/graphics/main_menu/main_menu_graphics.narc,/graphic/mystery.narc diff --git a/platinum.us/filesys.sha1 b/platinum.us/filesys.sha1 index a17ecb5da6..f43f3069c5 100644 --- a/platinum.us/filesys.sha1 +++ b/platinum.us/filesys.sha1 @@ -207,7 +207,7 @@ e7266bd8b7095861b6e1fdaf4f13cb648a9c325d *res/prebuilt/graphic/footprint_board.n 24760aae84c838f66389e1de92bc1b1579f5d953 *res/prebuilt/graphic/imageclip.narc 4d1aac7d0014e2ffdfb6501b3f16ec2084d46e04 *res/prebuilt/graphic/library_tv.narc 44214e37e0345a75b00a1c01d46ca787cdba1fb8 *res/prebuilt/graphic/lobby_news.narc -428a40285a2c82705502962047f8cb9492ef3df1 *res/prebuilt/graphic/mail_gra.narc +428a40285a2c82705502962047f8cb9492ef3df1 *res/graphics/mail/mail.narc 1d70dd8856d2f85beb2d4e461cfaf7179153640a *res/graphics/start_menu/start_menu.narc 5ccc879d6b89822eff8adeb0637af9f06c7d640d *res/graphics/signature_interface/signature_interface.narc 0f05587c988da3072761675d31b6bf94c9928d65 *res/graphics/main_menu/main_menu_graphics.narc diff --git a/platinum.us/main.lsf b/platinum.us/main.lsf index 0488144942..fc00f8f1d7 100644 --- a/platinum.us/main.lsf +++ b/platinum.us/main.lsf @@ -335,7 +335,7 @@ Static main Object main.nef.p/src_unk_020972FC.c.o Object main.nef.p/src_berry_data.c.o Object main.nef.p/src_unk_0209747C.c.o - Object main.nef.p/src_unk_02097624.c.o + Object main.nef.p/src_applications_mail.c.o Object main.nef.p/src_unk_02097B18.c.o Object main.nef.p/src_egg_hatch.c.o Object main.nef.p/src_unk_020985E4.c.o @@ -1267,10 +1267,10 @@ Overlay options_menu Object main.nef.p/src_applications_options_menu.c.o } -Overlay overlay75 +Overlay mail_viewer { After main - Object main.nef.p/src_overlay075_ov75_021D0D80.c.o + Object main.nef.p/src_applications_mail_viewer.c.o } Overlay overlay76 diff --git a/platinum.us/sbins_shared.sha1 b/platinum.us/sbins_shared.sha1 index 4e7cd708c8..d26add248f 100644 --- a/platinum.us/sbins_shared.sha1 +++ b/platinum.us/sbins_shared.sha1 @@ -74,7 +74,7 @@ cf86b18a15a2b011fd0e7c98379a9fa228c3fc4c *trainer_case.sbin 39a79a31811cac6b1a90206e67624c0a3179bd46 *signature.sbin deecf01a5608b25883804ef30c9d4c3d0c904ee5 *rowan_intro.sbin 21e3d2a2fb36d739f4fd16792719bf6fa7b7e6aa *options_menu.sbin -88ceed815cb9a2ef6e0d2dcedd2fc126e717c165 *overlay75.sbin +88ceed815cb9a2ef6e0d2dcedd2fc126e717c165 *mail_viewer.sbin 13777fa8b44e026c4eb960cce2309451c4594726 *overlay76.sbin d7a304050d0049809b21cf75937e4d14aaf858c5 *game_opening.sbin 8571cf57764db093c9ce385586894659297b783e *choose_starter.sbin diff --git a/res/field/scripts/scripts_common.s b/res/field/scripts/scripts_common.s index a85f7233b6..2d102c1911 100644 --- a/res/field/scripts/scripts_common.s +++ b/res/field/scripts/scripts_common.s @@ -1055,7 +1055,7 @@ _0E83: _0EAB: CloseMessage - ScrCmd_1B4 VAR_RESULT + CountMailInMailbox VAR_RESULT GoToIfEq VAR_RESULT, 0, _0EC6 ScrCmd_1B3 GoTo _0ECF diff --git a/res/graphics/mail/air_mail.NSCR b/res/graphics/mail/air_mail.NSCR new file mode 100644 index 0000000000000000000000000000000000000000..2ba11aa63bede59479a2219f8d4ff226eb6b4b39 GIT binary patch literal 1572 zcmeH{%TB^j6h#+FV;G!)13$nADo+taL41G~C zxD84`PW0SR_V&i?@ik+aYKfBW`-&e5!(pr|!#w!Bji_`hba z=2eL~@46X^|5xvQ_kYUX|M#8&O@ITSQAdxy6Od47Mg?#Mn2cvjk^}?IJZz5aF^Q_Qrd>YKN`IAg*(>6dJ}s0`cj zlZo}*ExFz;xy(rlb7Z&Fmt6RFcms!kl9)oO4#R`ZtQ<-XLX00oKip*UsB`?}oxn0j zGUxw^4f&^-Ub7Z_T+5*MPo3+*=lRAz_cMJvH?ttBf6C(&F;S^TQO%Zo#u=GYf;hIw zr>=iG{87>Y_W1joCUz-0xocX`u2kFTlMfj|*+taV75En{Bz;9Mbals)O|$0)%kxk zdX%|tsWIc5q~+?2f136eGcHnRoVncjJ(J&GjuUqB)(@GM9Vm24-6o+9ihoa6KbLh* G2~7ZoCMC@P literal 0 HcmV?d00001 diff --git a/res/graphics/mail/bloom_mail.NSCR b/res/graphics/mail/bloom_mail.NSCR new file mode 100644 index 0000000000000000000000000000000000000000..3c7a85dcb5283dfe76e1122bdd470ef5c5d31508 GIT binary patch literal 1572 zcmai!cUToi6vcm6cXUbife9#}2vO-pcqqju0*V!tDi5)zVR}eUETqTuXqq8P3JU23 zqUkXjQ#DP~d+)t#ie`3R!7u;ho$uQ{bLO6zJ9qBBx{CU$y?c=4elP%`s;;6wMssAd ze(0a(!x$dM2$C6L^^QZ#)l*2-&;KHgbTY!oB#Ufv!sEb9j+Jd?F_K*J@Zz=d^vFd% zqZn=c1r$<5F=OyCmJ-HMs>d!$t#MX~HP-U!86RboGoA@lFp)`2W(re{e;Sn<)0x3c zs;H)hTI#5$&Z@O)tXVYR52BITG%<&{%ws+aSZMr)5@8g#o3(0xtz!O zT)+x0}Xhd7c+|G2pk|+&1Za7V{Dt?2WeDe=oBm=-2K_tjzxbPf*u!4^mAW@B(ntDAU)4v6vP6k{ex)oW(ogzJi#fk7 zJM?-XM96;HxxYBZ?~zF3iBujHWth7{l=8>`$x{p7!PT=i{h>UO@ksgmH z$}r>icp?ro{%DDjfig&ZPOQW#pW}1lBwpfGoZ+!DScXV~B&Z>3s3b~~6gfpsl1fwu z$uQ|3(ZX;UA<2?Oilj=aN>N#)NxGz~G|hUoz(0o9$&gIRR2j;vYv*DMS&}U|GE#CS zPx4f*@=Cspl2IyOc~wXoEd@aoN|6+)LgkK&WsLY_tdz(&DU~uQmvU96#>)h$kP0Vw}X58-_KN;CY3T>X2?uk=_;v~YE`BD)JUz=sv6A#TAggCUS^5g!Ta|A z)Cf2K2JuU=r@+%Fvt_nwR0WzhNt1a8v^g?Y=E;0nAPXg$7>#JljVd<&feiW|#1cn5 RgBd~sLrK&aYK1&W{0qjL9vuJx literal 0 HcmV?d00001 diff --git a/res/graphics/mail/bloom_mail_tiles.png b/res/graphics/mail/bloom_mail_tiles.png new file mode 100644 index 0000000000000000000000000000000000000000..a20e99856b6e9b3f31e84247cacd14f96ccfce99 GIT binary patch literal 3157 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 aWc4q_wZ~soUj6&&wmNEmr0fvo%D(_|2CPv4 literal 0 HcmV?d00001 diff --git a/res/graphics/mail/brick_mail.NSCR b/res/graphics/mail/brick_mail.NSCR new file mode 100644 index 0000000000000000000000000000000000000000..2e91a133b8cd02249b8546a8785e21a465a655ab GIT binary patch literal 1572 zcmbtU+fu?X5IvpA`0Rr}pn?io(271Nvk;tcFe_hdK8*|SMV z`t$f_0k5Ge*!j>&)32Hq+j-3 z=4IXNc?R?QrvIxtTx66wXg2fn`TwT|nX^j&<{Gj$g87U3MW-O!eHjy4r(dcNl<$PC zLin41-apZtucGPhUkkTr8)M&g5sFJRJ8HT6cL%ZiHJE2)^ZfoIMChQ4uIi|sLlOFE zjPe5vjXk7(h=F^5wCBj&{*fX?-L;4mKbnfhu19?T#!i1v??1s5Q#Db9o*bgsv(83{ n-5aH|pp%JH{V$lM_Uh0KSxln@^VHr_pQv~J|M7v(E$j=w{JW$4 literal 0 HcmV?d00001 diff --git a/res/graphics/mail/brick_mail_tiles.png b/res/graphics/mail/brick_mail_tiles.png new file mode 100644 index 0000000000000000000000000000000000000000..72ad4f61e37624c5de3c973c8261e9fe2bf95332 GIT binary patch literal 769 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5BsiFXq*B~vF(7pyz$e6Y$&znbSDS;nqbw~g z|Ns9V6}4tgQqYv*s5MiX=Trw(Ck5@TPMXu4b#zMi-sa*t#YuCHW&xEQT{GpKg24YZ zdo{00%z4+%Q2f7o@4Np~_Wr;33}g)qfK(oRCm^BFj0#}#SmQz4^xPj$7srr@*0yu`MGU^5?=kQ&Y+zXMlc6G?VZ#2#Ke@^b z8LU75`CTa99CNXbA?TM}!<2v4OcOrmPyJ)hFmLYiRZ-V%UvDezy0vZNwHde0zAh5J z_~5GLb$-v1JzM;Cne=|HIepp3`}WboTYn_{c~Y$#IJdG)Vz?7j0(FNW4Af~^HgF)zY)VuD^EQTWMxW}Kf3j-OB{?3b&U|6@G zmEl?b+x^T3_%oPnN$X+rj#d19sdeWf7>DH5Mh2!_>l*L z!9EQZf#2Ji1K#+uDA+z^H`^}BaOQAKnZ{ebTz#gFzoKtWE9Ou9s>>3&q(h;K>Cta< z-K|mPYpyWfYQ7cApjgb;urFA~;pOFn?c13etQxQL2FY%iB5cpp(B{pk6Yb9ykaw|y zV=d!}9kCk^S47YHuct0|jh%5r0Vl(E9|o`e!f$^`Fv#V_ZMel<{rkR#kKy6$uM7=>cHxuj+2$`h=leIBdBNTLrFZt9XAOAI-Y~5>Y{|__ sM;Mo=NB11Byy}!NdyD?Iy+7+2Kk?6*Di*%tJ1Bj4y85}Sb4q9e0HnJ*Z~y=R literal 0 HcmV?d00001 diff --git a/res/graphics/mail/bubble_mail.NSCR b/res/graphics/mail/bubble_mail.NSCR new file mode 100644 index 0000000000000000000000000000000000000000..907f20074674bc623aa42afa089e004e5c7e0815 GIT binary patch literal 1572 zcmbu5*-pbS5JgX<2=TxJ4}1Vi*|$(ifwB`QOG}WFALh#dyRPG@V+hC@$-ef?xie0g zSH;&SNoNigNhr#^T2h+iLoMo4dYP4oSY?e)M69#HW<+eU%}zw@vd4Zz9B@eX?>MT7 zuHxNEI=Ne?WZr1a%iG^-b)BF0dFk~R-NyUJ(jjGP pnrq1;!$~~x%nPqdhm@&lu2s#C7&A^s>5!0WlIEu3jUpo6`34>3oq+%V literal 0 HcmV?d00001 diff --git a/res/graphics/mail/bubble_mail_tiles.png b/res/graphics/mail/bubble_mail_tiles.png new file mode 100644 index 0000000000000000000000000000000000000000..74208b79d6fc634ba998974e1aa7d929b83043cd GIT binary patch literal 831 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5BsiFXq*B~vF(7pyz$e6Y&Dp(KSDS;nqbw~g zK`Iy+IF|eel2LpAXPy0D{p|mg|KG0u2Z;c||NsBz9L-{2*qb%w**gV+|7-SYUX_^h zuA8CwfA!vX|EKKzfA1MYC4>a3KYH|?fP_LbDnM3)#(uUWNkBj#D+_1~QJ_fOIz!H{JHSqHv3E^efwz3-kP3pDW!g zQ@HtE;by$Ua=+<|?CNx1J#G(VelUma!CtlvI_r54lrq$?CsZ<5_ zTT;iuoqzt=CB%J5BvK+`ap_jE|G7I_em{1&x9)pAgF@4kzzIfNvn2m2HQeF+vHa6j zrT7o)1@5J67qC!jNHUjy&gaCybkk~v+FZW=zv>Lqj4TFcinnt&SUnJJ_`=I@g+IUM zcKxpA9sVo=4)5>(PG(dvT+LAMWMZ}ChmR_LO*0N&xiy9H&eSp{gSku-Ej|}=y?C=+ zAm7vQh15-T2So=>)>D61GVEv!*=p}3=)rv_8hOSf6NREcU@nsX(_D3P&kPxs4i5&(4hP6 zMurIw?QcH(xP_s`lj{LbhSBuf$_zJ(Y_Ia1=ASMnd_aY@jpYVI4}VOXV^tMf2$K=( z8b(q7m=8P*YK@)sr~1YI?p`*L@yi>Y6_b=Km<4hfIvaLn%>6l^!J=PsgET`VoBF@X p)(wmSm3P-XKl}Ico8Ihv2KkleQoBEkCrE>mo2RRv%Q~loCID0fNTL7$ literal 0 HcmV?d00001 diff --git a/res/graphics/mail/flame_mail.NSCR b/res/graphics/mail/flame_mail.NSCR new file mode 100644 index 0000000000000000000000000000000000000000..969c3a2cd55b8b75797c6efa7f9160a7c14dc5b8 GIT binary patch literal 1572 zcmeH{+fKqj6h&8)3GrbbeDDWUiVUJuK@sI9RqX@VG>P0@X94v$0LfvWJ5aML_!|vn`{-(Hf4M&IpwPz;j0*G;$5+O)|8>D7kr&P z_Qmd5xA+DD2ONssGf)k+IKN4YBaX%H+0sq@!?%S#5xZww*?fmn&cyE7N%38JGQZvm z*-i0z=4XHZ|NPuH@9WJVHUDDs>ob_|-sk?gYM}bx`)?R>zM_WK{WFXRx!{tkUz%ae zbxLDx-~SOe+;Ydg@L6p+|3JhePr_%l<@_@-2`|EDwZC|Ot)lbEm;c`@Zw2(u3^(Ga Au>b%7 literal 0 HcmV?d00001 diff --git a/res/graphics/mail/flame_mail_tiles.png b/res/graphics/mail/flame_mail_tiles.png new file mode 100644 index 0000000000000000000000000000000000000000..862167cf48779d8b112db396084c8d17313039f8 GIT binary patch literal 980 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5BsiFXq*B~vF(7pyz$e6Y$&znbSDS;nqbw~g z|93b4Z*Kno|Nq{5|NqZv{=cO8|Iz0E_nQBIYX&NR_x~ACYR=KDY6Xt7&BgB&1pcqt zt9eyo&bw}g;{Vlq-~FGm_y4_TK$UO+RDbm7I{^uWW>f%IfXR5aBuPL(AS){iQwpny zBs!CBXC_F^y7xTs&U$8zr@I-F zVp4Za+2ZRRwb0-D_34~qUxo$yr!$;bq0b;NT_l>rg26+XA?hDPg7H5=hwLqZA5NDZ z*gM~FyU}{np!>`cuWA_?W-VQEp3#M`ddZUh2OeUJI4_9Ta4|^UKKq)n;=f`91Lxd2 zK8Hhnq3@M8s;&5ybEl8NZ1QKho+Y~(ru1aZ|Ko4$&%TY}O`9!)Lp49+l~>bGy$_Z5 zJ*v&HvMTDIB*TaO%hZ=PFgM)hlKdmsVAUV8@7TeRJ?0&!*Uw@w$U3iD{_Xsdx-93$Z9nz4C_by(!+Y_`oN2~yBMei2 zF>lq%_#OY`dBrl*?9yD5vQvAcH>DKk} z%XK3eu4o80C^0OmYIC$Wc#iqN?WrqRrRU6={@3oXC*val^&2Oj6x`nL{c$bJ4^hkK zC2zN@BrNAqW+<5bWio@r^t%_%*u}l%V{|wx)Odr#gY7}=TGb||83F?TUw@fVC)IG# z-{zA(OWS+@Klw$q2Y3t^wlzs!;7Cc1|Fiyb_bp+@gp-T^M_tXbmJ<$ODBJ$-Usefk zvoq%!MSb+=Ueu(<#L literal 0 HcmV?d00001 diff --git a/res/graphics/mail/grass_mail.NSCR b/res/graphics/mail/grass_mail.NSCR new file mode 100644 index 0000000000000000000000000000000000000000..6982fabee2a50ca9c87ca93c4fe23832373d98a0 GIT binary patch literal 1572 zcmbu8Wq4Fq5Qg8cP3X4WwzQ>!7swJEg1ZHR1md{6OM<&=AORM4ch}&-Ex3k|P@|>p z-a^kFlC3;X`-eNvnLG2{d1vmq5)l{~^7s+*%LJJbArXO*Sxk%)jWdUd^N{x`EFXTj zjOEAQ_yQEPnTtXcrijssn!FgrDM0`MJ|)d6MQO@V*68KTDsT7-RHPD>sX|q%QJosp zB#>IvCWt!Jr5^POrU4BJA(Sw}i6D|F8qwJDE}GDkX2zP+f|j(RHEn21JKEEMj&!0k zUFb?TlXo|(2R-RUZ~D;J^3lZ5kNyl`AcGjp5QZ|0;fye~BN@eL#xRy~jAsH9nZ#tK zFqK%QG2QZU#504L%))JLHglM3qIt|uSKKTx(L$RovVO7Qm!$81Da%;S3ahVV6{}gp zTGp}N_zi3{`X=k$Y-WqCaq$RQ4Mgrg*KjN_c( zB&Rsd8B=+dbDZZw`twWTBA2*qJ6thzhFvw$HLi1mn^wEUZSIh4>h7BPDcrMsDrwy3 zU8BCo`+VS~GrIhB{*VWJ#K%136Fw!)ndq5KYRjT^9|qf9pCc< zNzNbb{Ga%lU-;GXzwtYNcso4evH8|L^JV-qde(R!`N~ZuJtv2rmuLP9dQncjq?h%I zGV4{nW{KC0&!RWr~VqCff}U28ls^Zrr~z~ zE=DNOF;b%x78JekC za%;BcXs+gIz7}Yq7HP4TXsMQ&+T~iIm0G3MTBEgEr}cm1H)x|aX|uLytF~#oc4((| zX}9)hul6ayRA$(I9ne89|hlq)zFy&giVp>AWr|Nf*6DMxQ5V z5AWiVF6)ZrJw5(yS9R?_=#1xoT{m=7w{%-~l&rf-(LJRqP4|_RY-A^g_wN5W-NWZ3 J*Hc(-{si7xSStVk literal 0 HcmV?d00001 diff --git a/res/graphics/mail/grass_mail_tiles.png b/res/graphics/mail/grass_mail_tiles.png new file mode 100644 index 0000000000000000000000000000000000000000..5a8d3352571924d3c91f5ccfc3d2e06b98321ba5 GIT binary patch literal 3504 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 NBYiWyvUB*m{{tD9F`@tf literal 0 HcmV?d00001 diff --git a/res/graphics/mail/heart_mail.NSCR b/res/graphics/mail/heart_mail.NSCR new file mode 100644 index 0000000000000000000000000000000000000000..a87e3ec7a7b8ff7db3044f9e048b34f47926f61f GIT binary patch literal 1572 zcmbu9Sx>@16on7Tjp@TY_~0KCa{Ner*S10Hiap*`Od4v+A(+%ehm`EKVlZ*|Y zMg~?uS>%w%E%KD3EQM#m|1vDi#QI^rfFfr-6)8L`&^AHF+bH?0ml1rI$o3Otd|640 zq_UE)9ONr%UJLG4<}1wWfOP){`LdF?wW_j$D%ncjLJjrEggVvy>Mh9jFKTN<@{Ir; z&0A;!(T8}^i5?s{)RVB{>$ZQUmSX>x>7Tzo z?v7BOyz@K25F?B+rV+{AfbOv`j~DmH1P@#jUaQPy*c4_c!^HG&eM1{)L*`yF-_bN(G4C+HKu9D1g3 literal 0 HcmV?d00001 diff --git a/res/graphics/mail/heart_mail_tiles.png b/res/graphics/mail/heart_mail_tiles.png new file mode 100644 index 0000000000000000000000000000000000000000..209f0932b4b41b8e76146ad3b9bd8b3e3eea10c1 GIT binary patch literal 787 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5BsiFXq*B~vF(7pyz$e6Y$&znbSDS;nqbw~g z|2r=EUwsxR^Z);UAPEFlCA$B6?fu`p_y5&*{{{BG6X>3EGz%#Et^4RZ1%dx-_G(_0 znDefiq4BBoEN*s_yn!XCEQ`q>-)-A@r0Xc7}xEH>d%IX8!bLQ}&R;SYD28tfVBeOw&W zX1>-}nZGpWNhu>wz1V>d`vV!CpXdAUe_*-g-JZInJ=eM(L}%?iCUIy+k*4Zow(qa@ z=Bi(oTXQt+c6`}AmD7{`TDu-Iotk8wtf%D97}v*TAbXWvMp5j>l&u_lE@v{TF8x%; zIGI!Kk(0!RnSwu7-|}Wm+sm%kaK6Du{D2_iv^WN7#XbgIuXy(Qr?N{Kp7c-Teo)OI zb8FXaafhGkHYd`LSTatH3FqFiDuB`AOw574>%s>bB`;J*Y-|o!}yVo#FTtS9QB+2c{(d%5Zm{u@ayUbc^%W~t@5{BJrOBilz zw#Q3ka4WFc{Chja%wFxX?_Sjdw_R))t9#jRi6rnu{FD7@Q?K=9<2|v4_jhy|H$5|D zEZA|>etrt4^vQ09-$~a672-waaZT8MSl@Bszrsx_mR;xDcT9C<__^&Z=ZecMsa4;@ zSquznPpvFTb9lydY#xKKmc!N$tXI}GL>_c}u-W*??@iAC>|4IgWtaFFCk0A1p00i_ I>zopr0PnIrG5`Po literal 0 HcmV?d00001 diff --git a/res/graphics/mail/interface.NSCR b/res/graphics/mail/interface.NSCR new file mode 100644 index 0000000000000000000000000000000000000000..89d5f1fffd597847fcf21688123108d0b5aa28d6 GIT binary patch literal 1572 zcmds#F%H8Z3`HHFlmsGm=m9)<^MV?J4vAR(}C*>pqJB literal 0 HcmV?d00001 diff --git a/res/graphics/mail/mail.order b/res/graphics/mail/mail.order new file mode 100644 index 0000000000..6cdefe4218 --- /dev/null +++ b/res/graphics/mail/mail.order @@ -0,0 +1,37 @@ +grass_mail_tiles.NCLR +flame_mail_tiles.NCLR +bubble_mail_tiles.NCLR +bloom_mail_tiles.NCLR +tunnel_mail_tiles.NCLR +steel_mail_tiles.NCLR +heart_mail_tiles.NCLR +snow_mail_tiles.NCLR +space_mail_tiles.NCLR +air_mail_tiles.NCLR +mosaic_mail_tiles.NCLR +brick_mail_tiles.NCLR +grass_mail_tiles.NCGR +flame_mail_tiles.NCGR +bubble_mail_tiles.NCGR +bloom_mail_tiles.NCGR +tunnel_mail_tiles.NCGR +steel_mail_tiles.NCGR +heart_mail_tiles.NCGR +snow_mail_tiles.NCGR +space_mail_tiles.NCGR +air_mail_tiles.NCGR +mosaic_mail_tiles.NCGR +brick_mail_tiles.NCGR +grass_mail.NSCR +flame_mail.NSCR +bubble_mail.NSCR +bloom_mail.NSCR +tunnel_mail.NSCR +steel_mail.NSCR +heart_mail.NSCR +snow_mail.NSCR +space_mail.NSCR +air_mail.NSCR +mosaic_mail.NSCR +brick_mail.NSCR +interface.NSCR diff --git a/res/graphics/mail/meson.build b/res/graphics/mail/meson.build new file mode 100644 index 0000000000..b8d9275c27 --- /dev/null +++ b/res/graphics/mail/meson.build @@ -0,0 +1,75 @@ +# if adding new mail files, make sure to add them to mail.order while keeping +# identical file types together (ie. new NCGRs should go with existing ones) + +mail_pngs = files( + 'grass_mail_tiles.png', + 'flame_mail_tiles.png', + 'bubble_mail_tiles.png', + 'bloom_mail_tiles.png', + 'tunnel_mail_tiles.png', + 'steel_mail_tiles.png', + 'heart_mail_tiles.png', + 'snow_mail_tiles.png', + 'space_mail_tiles.png', + 'air_mail_tiles.png', + 'mosaic_mail_tiles.png', + 'brick_mail_tiles.png', +) + +mail_nscrs = copy_gen.process(files( + 'grass_mail.NSCR', + 'flame_mail.NSCR', + 'bubble_mail.NSCR', + 'bloom_mail.NSCR', + 'tunnel_mail.NSCR', + 'steel_mail.NSCR', + 'heart_mail.NSCR', + 'snow_mail.NSCR', + 'space_mail.NSCR', + 'air_mail.NSCR', + 'mosaic_mail.NSCR', + 'brick_mail.NSCR', + 'interface.NSCR', +)) + +mail_nclrs = nclr_gen.process( + mail_pngs, + extra_args: [ + '-bitdepth', '4', + '-pcmp', + '-invertsize', + '-nopad', + ] +) + +mail_ncgrs = ncgr_gen.process( + mail_pngs, + extra_args: [ + '-convertTo4Bpp', + '-version101', + '-sopc', + ] +) + +mail_narc = custom_target('mail.narc', + output: [ + 'mail.narc', + 'mail.naix', + ], + input: [ + mail_nclrs, + mail_ncgrs, + mail_nscrs, + ], + command: [ + nitroarc_exe, + '--create', + '--index', + '--files-from', files('mail.order'), + '--file', '@OUTPUT0@', + '@PRIVATE_DIR@', + ], +) + +nitrofs_files += mail_narc +naix_headers += mail_narc[1] diff --git a/res/graphics/mail/mosaic_mail.NSCR b/res/graphics/mail/mosaic_mail.NSCR new file mode 100644 index 0000000000000000000000000000000000000000..800afdce2930164d28ec9081a077b197d7654c14 GIT binary patch literal 1572 zcmbu9*;2w#42FMhy!OHuP;s}28>oPSfPw-l2rA&d;fnkIa6XxuWaJcwo@%AvOeZtx z|0hjPnvLc%pC53!TYy%$kjX}KZ4|@xPB*$JZbwHGbi$1;bQ3*7FPJ`|9}MSo*#Qia z-hc-~@M2gP0W&I$f$<8B*>U*3^?pnUlVGNV0GOa)oekCLga2>{VOr|Xz;9DU--D?S z+xDq*h^YGEU*6Q(A%a=yKMK}cKf|-sP14lIw9nXmi@2&Ev#FwYh+|Irp9kyped-)c zeM0n39g?bk!ojIC=bXfX^uGw!|NY$7987&m^iCbps(y-2zq8%p9@1)mGFT#(g%vPa zAqR$YR@qgh&!d1fVx8DPQ7EB|5;lbbfxf dDB_y9A$ShAxWm2h0Ok=-c&797g4ZT^!xuGX$IAc! literal 0 HcmV?d00001 diff --git a/res/graphics/mail/mosaic_mail_tiles.png b/res/graphics/mail/mosaic_mail_tiles.png new file mode 100644 index 0000000000000000000000000000000000000000..73cbf6e9021d0b45f5f9776bdeccd06e0d9f15ef GIT binary patch literal 839 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K56gZfHspX>HkOP9R2^S`~UxYXTSYFd-ngcv(Ns2JNtjm(X61Ls4ZKzyi*YP zzh4wn{~O1d6S)RQ&up5;-#T@Z_~Hq! zjZ-?R;w@KfD+tJa8Nk9I^lrc6!++Zka;?ycZxGnWpt)Xm0T)Y$L&G1=9orfd>P4T3 zPZDI{$@<^>@Xi$OC)^JnX*0(B(dK&a*;(no|ACv9lc!`ZyV5yj^#rGoP|n_k>vTehljAdY;Sz>dKTa{M7kqI40l&xtmU!ueiq3`~?`k_5?A#9&Y-+g2e*XHy zpHVjVEq+8W?l}C#jQjl#t1E79+zk6PrwHa|aV>Ncau;E658Jx+qUIW@LYYd2H4Im; zJzE~**IFUE*!Xd(Oz44a6Z`WP&ArUOPU-NeCFh^B-oDPY!25v+W9hfE@3oj-Srz}< z-Pdr2^@1>~N!9N-Mz#9SN11q9`TDnrF)VkSUk)a%PqXCTec<=xU{TWBs-$D{4jeB# zbKLJwo23G0$G?4-IUaX)@?7F)S`qZDi(`S;jPN*ZIfaZb9WyfvB4R$yJTzC^eCq;l zJC2{9BLxDAZ>KRPYU;-^<*PQFeIIt9_x3l=jB6Y_44G`^sWu$tO8ESKO+%+U(~I(X z4KEHJYhswgn{ivQA$5C$`~7s5Bm8Az+6T-9I46Ahzj0sj?JC9(T#O8VHoslU#qs{t zM25?%37_*G{8I6Zx~HR$`_4?v;Q3zqLMPwXOJ& Q7$}u_y85}Sb4q9e0AR3kkpKVy literal 0 HcmV?d00001 diff --git a/res/graphics/mail/snow_mail.NSCR b/res/graphics/mail/snow_mail.NSCR new file mode 100644 index 0000000000000000000000000000000000000000..5412750ad496f08fd6e448f6e820a142bc662ce2 GIT binary patch literal 1572 zcmbu9cX(7)5XFC^F+_@J`GWarzv=gr)6&dh!9ZCOcqX+u5Yii8-1 z(z25BSjEUPUG$?kj`$`-0*SatBAFE28mVTrkT2Rf$W0pU^(tMz8FbLKBb~@peiqr} zkV_u<6i`SJ#dM|%UFpU-bf<)K=|N9=aUQ+tLtoD40!q1%iwwUXWt7vO0bI-_T*_rs z;Nfzv;7YFIY6dchYq*x{xSkudGMF0~LM1mb)bPCw<7TS3g{p`O<@(}Q2YI-S;Z$?G zld*P;poTmA{5u&LRI@d#K5SgeCDQHW5qFeqpkBB%RSs1 zq+LO%TezNwaf~Qu#hK1da#`AX#=i-+*3Sl_|Nbxbu3~r&l!cPsONcs7kP=7L+**C z_6o21pTyVv=l42q@Fq)G%3Hk6JG{$#`fOIRjQ9C~5BZ4Ytl(olQMFG^FImG{*6|hV*}z6Nv6(G=%~rOtogK=m(eF-n8T1X`@*UsvgW>OH4?pq~Kl2NF z`IX=Joj=&epZvvs4)C|C{$qTtuB`Z%gSsB#u>bsyP)~#Yt04^$bq*4-bH~WB5+TP) zq*&}4nn{!#FDFQIvEH9(IZ;kht}j|RD8@l8rInm4v2u!>DyPZm(pu_>l{4f_!}oHQ zobBvwvvhL~%)y;U`OqxFuEENt(2mbjgqoiqfQ`qE3>jktOcv ZY`w}+oNF?9k}n0~()Yhmikc9`@*me=AFBWW literal 0 HcmV?d00001 diff --git a/res/graphics/mail/snow_mail_tiles.png b/res/graphics/mail/snow_mail_tiles.png new file mode 100644 index 0000000000000000000000000000000000000000..5bc8937e2f70c0baad7ac44ee5ed704b67a0eb07 GIT binary patch literal 2790 zcmZuzc{J3E7r)kS@H;9Bt(%%iIJhPHnv2{ z$RtT265_QWqQ;tMOEf?4cYf#m&hMOe|G1xf?!BLT|GG<}t+lxbQGy5nB8Myv*a0Bx zCfE|N>-vd_~y|H#lF8ccVy}gU<`(uCS{YTggKC59-xtAZ#Smg8h zW7CW5-bKbUU+@g{Wi?F8lKJcg#;SJOL^alRN|IycLth1gynE_K9O}fEd(Gd# z&F%ZzZGL-tX=P$Oz^0M67Fi#$x~ib`mUJdck$iJ)$K=j<73_i(w_-301OM7|`pswj zk+uEXgsEwX0$RJLe&C_+YmIxZ)uV0z-b^2sNgY_N&W(?JY)D7x-D0xsJxHBiqdPLI zy&@6~@b2&d*$6(p-BRl*EpyF%RASyP(jT(!1m`v&I0|U{``a6oBovT z@~c8_}%8OD~I>}Lo)V2#|^q?#81_B2Q%Nv6`M3BnsR+!Y0E=^fPbISO7P}l>B zO{qv`$_2a81-Xotqp$Y97Kr|NccBf3W?%M%JnB8KuHf@6&OQFdilzjbPt@j0)0~TX z^;9QGUQv%mm1gp4Hv7~zjYHAKz1Lp*-QlpLG08aP z=GR{spuCw~ucm%7FB9+)3V`#ji_^#NEV(05RCeNvOeYFjIcFd<1ih#HCIIicmO7Sp zxLpC8z|3>jE0`#suDMU9DSUXUl%@*zv0TkN%A`HeB3H)mj4R^N74Qiut@}ajrLhIN z4)_L#CrHW#coYSA1w3dJGF}yaFKDZb}r1zQ1 zV8I`A+Tp-!zl)##)pYVf<<;t(TQ)+?>Z!OGZxRkJMY@0dvecvvA(siX3AonYa|G*R zwzc*TZDvRQV;bKC49oPZY^!13fxta7av42Jo_MYdCule7vEVz_dZf@Q#IJOUctT`A zEnMnF1+q+@wF_Kxr0CO9YX$VOU$OmMG|9@`i#G+G(+aQT5U!>le(Km{rb0XV!!Q1> zqikt(RX{a`N}*W`9&ap94#33q|Fu);M%|-|44l==$?S0$rQX9ZljP82!B?x}cWH78 zf|F+g$!UPWXbt9IZSQ9A0t#?Eeb86egW8sj$b8opq8Bf@Z!;3@2sp2W{f(2mh|!|( z>7^W~ooo8|#N`ilgO(*Sx&t(j1g$K?dwUA7lftNkfNPE*-E~6yQNNbrP;9g33?>zv z`pp+^{kpY7n63*k#k$Hso>B0~j=V<=6-N*C65jpZ2o$tKoJF98zg2g9CIK80jr~_d zAO`Imf1^kWa;cU+QCwqp$!)Nin-DOeH^S>589qCsXD#QId-HijEoazhujkt*8#@+5 z&gAVi^r&$iRjUV|3F3RQ`SXt9+-XX(+&o^O*s!In_ieUa*I$rkADI6+dUvsw4 zyX&zdh?VTaGp$dJS1JMBZHPJTXN+Y^=)nEBdoFmo(f3A3rVzQ+Mz8v$D%KZhoU~#c z&^B`4Z&{x>s7GvfQLEgipaau?$7fB*?wtm7;SM4QD(V_$=~pSq-bbP_kV!I-(mgkAK%HDo#&d zI8$?6CcNWttZ9aZm5Hu}LGo~Iq=Mhm?@JEAMCKQ3jK6Uveld??$v6@=!Uty0ws(CC zlI}Lp3*Z>{wz8U(V!K6v1r%b_<4_OH85058BeZ*)#M_1XO97YlaOIg5NGetWl6Ec^ zM!Jr^+qe{VcC7(9YdJC0=f5Tj7zvUK!p)2#a>GVrP|mo4Qj@$(FE~}4M+Z0&4OtlK zot0gU2A2@jI7>hdHX?y4l^R3o$dDp-jdFyCmz=&+uV4cOGu;@W>sSV6R;&ymJB_WK zT!M2}^6F1&q&c6puKM>Ji|R+@-wcF;5OQCe>w6N01=FSf)!Y^|X+mSbtbAiHPZi&24Mbb3Q4SD+<1I7F;TP1y?Y+`l; zvB`2!r%jeU+D6H4J+;{2GOQ}zs@rZ4?Rcp~2VnTm7Ovu+I$KfDx?dEvF_$_ANb=}b zBptZokptawbw8`M?9)19xtpi<#<+S3ndYg8Dm=MdHlO~Cq+q}5Z2MN*lxN4zhL)9VIF{r+7!dlzVg1BP zpgSJ|ZHM_>y5s!0;?67WX2JH|iJP;H7arh_Qf_NQ>+w)02&=fwE2=jA{gq7%yFEg! zq|#~3;DZ3> z&A(`Y)N$5NDlM#gi_D5Z$(&C!a9_-X#%a@3k$KNC2IQ)JHiy}0+-yQ*{EY4usRj)o zo5&;fBxX6--{SOS{LBv<(s%zYXB<9JEh^badMDV1QxaI}P)s%IBL(%CSu-#MFK**f zJ<$APRUX$*=6O7uvC?HLtLQ2f)ZxkHYUNHogFdB#&bMsCbfo9KeHY`IU-#KEA8#PE zOEwAoSkNj-;wb8|j% zSO03;Gb|J9fk|Dw9;7ebJ5k`(u+$oAAU}7=n_~chh5BHx-79YxI zW%hFf=-U0SOvsP#u8PVod+2E(PFKG+uH}|;7@iy zsIIA~ZK*o4L>K+2o<%k}jg;(2TXKn$*GP#+@@Yo_t}lfY(cae*{@MYr&Jx%=(n;To z{k;-8>$AX=*70Q|j7ySo%6xklUAuA!-RRDt97Yd%Qo-RWN6?GjYE2l=H1L*osq|T^ zRdFPJIEtgGrZ4?Ch8k))mi`RjI8t?fAzu=)j6K6f@5Vp|F__~yffG52lR1SUoXSwr zddg`GW4Km!x_XAZ3p>QOxxB~{UQ+wZ>iG(<@*1!625<5fZ!_8~^`kFS`*Mvw-mKVx z?_yHs9ai$L+TUZ9`o7Nxe8_6n@DVf2R6b^uvGga*F>9G^QhMX->hI6xQ!M|PdZZa@ z*0X^jCis5N7kr6j(`@u(Z_+Mv`HD^T^>5~DzTsQGqsG4>>-)V*K>eUxnz`mjt-HG^ zXN%IF{@R)S=kgOj^9#T78^5dnM*iSW{^D=`;a|40jge-%=8f1c6KUJXV-Nf2TuEZrz@>SYNfw)pAmd|zK kPM-OHDU$Y*kPhOhbd*j~EF}^*`A%mkm9j=kX*4PS0WU-QrvLx| literal 0 HcmV?d00001 diff --git a/res/graphics/mail/space_mail_tiles.png b/res/graphics/mail/space_mail_tiles.png new file mode 100644 index 0000000000000000000000000000000000000000..7315ece07d1b7dee122a2c8a9fc558898860b09d GIT binary patch literal 1537 zcmZvcdpHw%7{`B`+mzOF6e%LdiHfr5xQq#F$aO=S>v8EY;iSymW`~}nrKOylG;_&} zlA<9omueAb$z4`BQ7qCzNXohTeQFF54P1~Uaz&DCu4H&py8cztJdY6)n#tlI1Oh=M62C?NJ9*=PL<1nZ;b3>dgUpy?&|=1pDq&7RS=!B#l&FZkKUr3U z9B3x7S4b$o#VS!*x#{c6bULOUBOH;zuc45v&cu@KtQY&a8yB+tH%Cf=n!IA*UR~;! z&1e}l6{VKsByjL=QmFN zy#(Kl8W9+4ygILTTO2;IialKz-)N&jC)d?l2E>_9P*$IHus98wz7@P2v|_U{AKjhD zg#z*VR&bNIn&eN|3IvfIRo*aa^iJ^sA86n!v+$=fZ7CEu6=$RljeRl$DbSwR1Dz7n zgW&bpYD`_V32-9|j}2-1=%=Nv^{t;=W`&k10o53JEw-t`tQ+z3M&Vg)DyGAN&?p9{Vnb<3~`SKF_dyUUtPWRQD#qKC7LC(epz2R!#4} zv%ljLI9mXdGsL1aCVK6lrDvx8I=?onqgS~Gn{~_D5eHNpFKM4_?okr3yF=z81mDw& zj;jz;ijZz))F~4Us-;PnR;d0i+z$p{P7nwcdT|455wr1DP8=SSGW} zU}i7@p00rFHfoF+O*2)M~8iN`JKzHXN-EZA_-M)c^MR-4QUI zWhj0JnO6?0r?=Cq4e)rV*4-HORL8&!NbnWRdY@rWX%k#a^vY^iC0=pqPB5Q;x8yA) z!P^_9?0$FSi*Q8)IGQk1&ChirPa@KyPh`Nw`n{Ay z;A1I^6xPq9jP*$){+)C7(e_ARs_>KaZTtTyo@)nSN9 z8tBWu!w~YH1%`rItY9d(rYRw9?!x)?Bn!tlPP77oolVy!&}VB|(fow1KU@Nbeied6 zbVp{<#bY{_*RELju*@up4xfXV9}Tk2zD&=2UedYfj2?)Xlk4OM6wGf2#S#3=S(-B} za5Hi(Z!VF2Pki6^fpP7;?&n&_D5a~#7F5mUKuZ0hf2^6OX%5RazoE49{REI3LS0{f z*?e3B<7e*&K1zXqD}xTF$U#tXIDA#rYT~9XLe~HXI?g>a*{{!$5$iT>A2d7zr3w zzK=j)j}X+p4zy(bfXx0y{?PbioCz2kzgvGU3Q>QB@~in5qVpHz*Yg+o|D``4rKrEs zynm(W{ADwLk>B*^=>h#6uUg;M4oxt{3^O&wIj1@1Ra#)dX`&oz!~UFqh!Bx!@S-I} z6e31~f;%C2VU?2ybP9Q literal 0 HcmV?d00001 diff --git a/res/graphics/mail/steel_mail_tiles.png b/res/graphics/mail/steel_mail_tiles.png new file mode 100644 index 0000000000000000000000000000000000000000..1b25138d0b61a33edc26fbd720be0800d32f4062 GIT binary patch literal 715 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5BsiFXq*B~vF(7pyz$e6Y$&znbSDS;nqbw~g zo12@zRTq2R3vyiYA1EIb6qJ>f1!T;bGw0~hqtBi_`~Uy{oTFJw{iF&6X@PEx- z&8re~-gPq+|F7Qr?*Ej%|L;8ms)qxh`lCnR2}mdaO-2TA1(=LyOOgZx1R(Ze%3_LW zo?XEU^xQE|7srr@*0aXXxq;raQW)(mI7zA`yX6?}HXk7-488s~x47vvZ=PMOUxWy)M#hF_wQ zXTD}89nYLKjgjF<>*HTi4vSd>7M)YvK3zqVA=CIZ^Mreg|Cuu%5ZygLo1rX*nPHJt zyiCKCc=?7TMJ9)D#jy+*3SX|?Epp+TDuY77FBXPfM_!&~35iRGh9&zh nFs5+cl+$_?(XjH?(WX>o{Tfj_{V$q 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 G3I9L&IDz^A diff --git a/res/prebuilt/graphic/meson.build b/res/prebuilt/graphic/meson.build index 2c5acdafc1..a70682d5d6 100644 --- a/res/prebuilt/graphic/meson.build +++ b/res/prebuilt/graphic/meson.build @@ -15,7 +15,6 @@ prebuilt_files = [ 'imageclip.narc', 'library_tv.narc', 'lobby_news.narc', - 'mail_gra.narc', 'ntag_gra.narc', 'nutmixer.narc', 'oekaki.narc', diff --git a/res/text/unk_0409.json b/res/text/mail.json similarity index 63% rename from res/text/unk_0409.json rename to res/text/mail.json index 3bb26e29e4..01021cceed 100644 --- a/res/text/unk_0409.json +++ b/res/text/mail.json @@ -2,19 +2,19 @@ "key": 59412, "messages": [ { - "id": "pl_msg_00000409_00000", + "id": "Mail_Text_Confirm", "en_US": "CONFIRM" }, { - "id": "pl_msg_00000409_00001", + "id": "Mail_Text_Cancel", "en_US": "CANCEL" }, { - "id": "pl_msg_00000409_00002", + "id": "Mail_Text_EnterPhraseOrWord", "en_US": "Please enter a phrase or word." }, { - "id": "pl_msg_00000409_00003", + "id": "Mail_Text_StopGivingMailPrompt", "en_US": [ "Stop giving the Pokémon\n", "Mail?" diff --git a/src/applications/mail.c b/src/applications/mail.c new file mode 100644 index 0000000000..a56f96b3fc --- /dev/null +++ b/src/applications/mail.c @@ -0,0 +1,374 @@ +#include "applications/mail.h" + +#include + +#include "constants/items.h" +#include "generated/game_records.h" +#include "generated/trainer_score_events.h" + +#include "applications/mail_viewer.h" +#include "overlay020/ov20_021D0D80.h" + +#include "game_records.h" +#include "heap.h" +#include "item.h" +#include "mail.h" +#include "overlay_manager.h" +#include "pokemon.h" +#include "save_player.h" +#include "savedata.h" +#include "string_gf.h" +#include "unk_02014A84.h" +#include "unk_0209747C.h" + +FS_EXTERN_OVERLAY(overlay20); +FS_EXTERN_OVERLAY(mail_viewer); + +typedef struct MailApp { + enum HeapID heapID; + u8 padding[4]; + UnkStruct_0209747C *unk_08; + ApplicationManager *appMan; + MailViewerAppArgs *viewerArgs; + Sentence selectedSentence; +} MailApp; + +enum MailAppState { + MAIL_STATE_OPEN_VIEWER = 0, + MAIL_STATE_VIEWING, + MAIL_STATE_EXIT, + MAIL_STATE_EDIT_SENTENCE_START, + MAIL_STATE_EDITING, +}; + +static BOOL MailApp_Init(ApplicationManager *appMan, int *state); +static BOOL MailApp_Main(ApplicationManager *appMan, int *state); +static BOOL MailApp_Exit(ApplicationManager *appMan, int *state); + +const ApplicationManagerTemplate gMailAppArgsTemplate = { + MailApp_Init, + MailApp_Main, + MailApp_Exit, + FS_OVERLAY_ID_NONE +}; + +MailAppArgs *MailAppArgs_New_Write(SaveData *saveData, enum MailContext context, u8 partySlot, u8 mailType, enum HeapID heapID) +{ + Mailbox *mailbox = SaveData_GetMailbox(saveData); + MailAppArgs *args = Heap_AllocAtEnd(heapID, sizeof(MailAppArgs)); + + MI_CpuClear8(args, sizeof(MailAppArgs)); + + args->mailType = mailType; + args->partySlotUnused = partySlot; + args->mailbox = mailbox; + args->writeMode = TRUE; + args->contextUnused = context; + args->mailboxSlotUnused = 0; + args->saveData = saveData; + args->mail = Mail_New(heapID); + + Mail_Reset(args->mail); + Mail_SetTrainerAndIconData(args->mail, MAIL_TYPE_NONE, partySlot, saveData); + + return args; +} + +MailAppArgs *MailAppArgs_New_ReadFromMailbox(SaveData *saveData, enum MailContext context, u16 mailboxSlot, enum HeapID heapID) +{ + MailAppArgs *args = Heap_AllocAtEnd(heapID, sizeof(MailAppArgs)); + MI_CpuClear8(args, sizeof(MailAppArgs)); + + args->writeMode = FALSE; + args->contextUnused = context; + args->mailboxSlotUnused = mailboxSlot; + args->saveData = saveData; + + Mailbox *mailbox = SaveData_GetMailbox(saveData); + + args->mailbox = mailbox; + args->mail = Mailbox_CopyMailAtSlot(mailbox, context, mailboxSlot, heapID); + + return args; +} + +MailAppArgs *MailAppArgs_New_ReadHeld(SaveData *saveData, Pokemon *mon, enum HeapID heapID) +{ + MailAppArgs *args = Heap_AllocAtEnd(heapID, sizeof(MailAppArgs)); + MI_CpuClear8(args, sizeof(MailAppArgs)); + + args->writeMode = FALSE; + args->saveData = saveData; + args->mail = Mail_New(heapID); + + Pokemon_GetValue(mon, MON_DATA_MAIL, args->mail); + return args; +} + +MailAppArgs *MailAppArgs_New_Check(SaveData *saveData, u8 mailType, enum HeapID heapID) +{ + MailAppArgs *args = Heap_AllocAtEnd(heapID, sizeof(MailAppArgs)); + MI_CpuClear8(args, sizeof(MailAppArgs)); + + args->writeMode = FALSE; + args->saveData = saveData; + args->mail = Mail_New(heapID); + + Mail_SetMailType(args->mail, mailType); + return args; +} + +BOOL MailApp_WasMailWritten(MailAppArgs *args) +{ + return args->mailWritten; +} + +BOOL MailApp_CopyWrittenMailToMailboxSlot(MailAppArgs *args, enum MailContext context, u8 slot) +{ + if (!MailApp_WasMailWritten(args)) { + return FALSE; + } + + Mailbox_CopyMailToSlot(args->mailbox, context, slot, args->mail); + return TRUE; +} + +BOOL MailApp_AddWrittenMailToMon(MailAppArgs *args, Pokemon *mon) +{ + if (!MailApp_WasMailWritten(args)) { + return FALSE; + } + + Pokemon_SetValue(mon, MON_DATA_MAIL, args->mail); + return TRUE; +} + +void MailAppArgs_Free(MailAppArgs *args) +{ + if (args->mail != NULL) { + Heap_Free(args->mail); + } + + Heap_Free(args); +} + +int Mail_TransferFromMonToMailbox(Mailbox *mailbox, Pokemon *mon, enum HeapID heapID) +{ + int item = ITEM_NONE; + int slot = Mail_GetEmptyMailSlot(mailbox, MAIL_CONTEXT_MAILBOX); + + if (slot == -1) { + return -1; + } + + Mail *mail = Mail_New(heapID); + + Pokemon_GetValue(mon, MON_DATA_MAIL, mail); + Mailbox_CopyMailToSlot(mailbox, MAIL_CONTEXT_MAILBOX, slot, mail); + Mail_Reset(mail); + Pokemon_SetValue(mon, MON_DATA_MAIL, mail); + Pokemon_SetValue(mon, MON_DATA_HELD_ITEM, &item); + Heap_Free(mail); + + return slot; +} + +int Mail_TransferFromMailboxToMon(Mailbox *mailbox, u16 slot, Pokemon *mon, enum HeapID heapID) +{ + int item = ITEM_NONE; + Mail *mail = Mailbox_CopyMailAtSlot(mailbox, MAIL_CONTEXT_MAILBOX, slot, heapID); + + if (mail == NULL) { + return -1; + } + + item = Item_ForMailType(Mail_GetMailType(mail)); + + Pokemon_SetValue(mon, MON_DATA_MAIL, mail); + Pokemon_SetValue(mon, MON_DATA_HELD_ITEM, &item); + Mailbox_ClearMailAtSlot(mailbox, MAIL_CONTEXT_MAILBOX, slot); + Heap_Free(mail); + + return slot; +} + +static MailViewerAppArgs *MailViewerAppArgs_New(Mail *mail, enum HeapID heapID) +{ + MailViewerAppArgs *args = Heap_Alloc(heapID, sizeof(MailViewerAppArgs)); + MI_CpuClear8(args, sizeof(MailViewerAppArgs)); + + args->writeMode = FALSE; + args->trainerID = Mail_GetTrainerID(mail); + args->trainerName = String_Init(TRAINER_NAME_LEN + 1, heapID); + + String_CopyChars(args->trainerName, Mail_GetTrainerName(mail)); + + args->mailType = Mail_GetMailType(mail); + args->language = Mail_GetLanguage(mail); + args->gameVersion = Mail_GetGameVersion(mail); + + for (u16 i = 0; i < MAIL_MAX_ICONS; i++) { + args->iconData[i].asValue = Mail_GetIconData(mail, i, ICON_DATA_VALUE, Mail_GetPlatExclusiveFormIcons(mail)); + } + + for (u16 i = 0; i < MAIL_MAX_SENTENCES; i++) { + Sentence_Set(&args->sentences[i], Mail_GetSentence(mail, i)); + } + + return args; +} + +static void MailViewerAppArgs_Free(MailViewerAppArgs *args) +{ + if (args->trainerName != NULL) { + String_Free(args->trainerName); + } + + Heap_Free(args); +} + +static void Mail_UpdateFromViewerArgs(Mail *mail, MailViewerAppArgs *args) +{ + for (u16 i = 0; i < MAIL_MAX_SENTENCES; i++) { + Mail_SetSentence(mail, &args->sentences[i], i); + } + + Mail_SetMailType(mail, args->mailType); +} + +static BOOL MailApp_RunSubApplication(ApplicationManager **appManPtr) +{ + if (*appManPtr && ApplicationManager_Exec(*appManPtr)) { + ApplicationManager_Free(*appManPtr); + *appManPtr = NULL; + return TRUE; + } + + return FALSE; +} + +static BOOL MailApp_Init(ApplicationManager *appMan, int *state) +{ + MailApp *mailApp = NULL; + MailAppArgs *args = ApplicationManager_Args(appMan); + + Heap_Create(HEAP_ID_APPLICATION, HEAP_ID_MAIL, HEAP_SIZE_MAIL); + mailApp = ApplicationManager_NewData(appMan, sizeof(MailApp), HEAP_ID_MAIL); + MI_CpuClear8(mailApp, sizeof(MailApp)); + + mailApp->heapID = HEAP_ID_MAIL; + mailApp->viewerArgs = MailViewerAppArgs_New(args->mail, mailApp->heapID); + mailApp->viewerArgs->options = SaveData_GetOptions(args->saveData); + + if (args->writeMode == TRUE) { + mailApp->viewerArgs->mailType = args->mailType; + } + + if (mailApp->viewerArgs->mailType >= NUM_MAIL_TYPES) { + mailApp->viewerArgs->mailType = 0; + } + + mailApp->viewerArgs->writeMode = args->writeMode; + + return TRUE; +} + +static BOOL MailApp_Main(ApplicationManager *appMan, int *state) +{ + MailApp *mailApp = ApplicationManager_Data(appMan); + MailAppArgs *args = ApplicationManager_Args(appMan); + + FS_EXTERN_OVERLAY(mail_viewer); + FS_EXTERN_OVERLAY(overlay20); + + static const ApplicationManagerTemplate mailViewerTemplate = { + MailViewer_Init, + MailViewer_Main, + MailViewer_Exit, + FS_OVERLAY_ID(mail_viewer), + }; + static const ApplicationManagerTemplate v3 = { + ov20_021D0D80, + ov20_021D0DF8, + ov20_021D0EA8, + FS_OVERLAY_ID(overlay20), + }; + + switch (*state) { + case MAIL_STATE_OPEN_VIEWER: + mailApp->viewerArgs->writeMode = args->writeMode; + mailApp->appMan = ApplicationManager_New(&mailViewerTemplate, mailApp->viewerArgs, mailApp->heapID); + *state = MAIL_STATE_VIEWING; + break; + case MAIL_STATE_VIEWING: + if (!MailApp_RunSubApplication(&mailApp->appMan)) { + break; + } + + switch (mailApp->viewerArgs->result) { + case MAIL_VIEWER_RESULT_CANCEL: + *state = MAIL_STATE_EXIT; + break; + case MAIL_VIEWER_RESULT_CONFIRM: + *state = MAIL_STATE_EXIT; + break; + default: + *state = MAIL_STATE_EDIT_SENTENCE_START; + break; + } + + break; + case MAIL_STATE_EXIT: + if (args->writeMode == TRUE) { + if (mailApp->viewerArgs->result == MAIL_VIEWER_RESULT_CONFIRM) { + Mail_UpdateFromViewerArgs(args->mail, mailApp->viewerArgs); + + GameRecords_IncrementTrainerScore(SaveData_GetGameRecords(args->saveData), TRAINER_SCORE_EVENT_MAIL_WRITTEN); + GameRecords_IncrementRecordValue(SaveData_GetGameRecords(args->saveData), RECORD_TIMES_MAIL_WRITTEN); + args->mailWritten = TRUE; + } else { + args->mailWritten = FALSE; + } + } + + return TRUE; + case MAIL_STATE_EDIT_SENTENCE_START: + mailApp->unk_08 = sub_0209747C(2, 0, args->saveData, mailApp->heapID); + + if (Sentence_IsValid(&mailApp->viewerArgs->sentences[mailApp->viewerArgs->sentenceIndex])) { + Sentence_Set(&mailApp->selectedSentence, &mailApp->viewerArgs->sentences[mailApp->viewerArgs->sentenceIndex]); + } else { + Sentence_InitWithType(&mailApp->selectedSentence, 3); + } + + sub_02097500(mailApp->unk_08, &mailApp->selectedSentence); + mailApp->appMan = ApplicationManager_New(&v3, mailApp->unk_08, mailApp->heapID); + *state = MAIL_STATE_EDITING; + break; + case MAIL_STATE_EDITING: + if (!MailApp_RunSubApplication(&mailApp->appMan)) { + break; + } + + if (sub_02097528(mailApp->unk_08) == 0) { + sub_02097540(mailApp->unk_08, &mailApp->viewerArgs->sentences[mailApp->viewerArgs->sentenceIndex]); + } + + sub_020974EC(mailApp->unk_08); + *state = MAIL_STATE_OPEN_VIEWER; + break; + } + + return FALSE; +} + +static BOOL MailApp_Exit(ApplicationManager *appMan, int *state) +{ + MailApp *mailApp = ApplicationManager_Data(appMan); + + MailViewerAppArgs_Free(mailApp->viewerArgs); + ApplicationManager_FreeData(appMan); + Heap_Destroy(mailApp->heapID); + + return TRUE; +} diff --git a/src/applications/mail_viewer.c b/src/applications/mail_viewer.c new file mode 100644 index 0000000000..d9fcf8e258 --- /dev/null +++ b/src/applications/mail_viewer.c @@ -0,0 +1,952 @@ +#include "applications/mail_viewer.h" + +#include + +#include "constants/narc.h" + +#include "applications/mail.h" + +#include "bg_window.h" +#include "enums.h" +#include "font.h" +#include "game_options.h" +#include "gx_layers.h" +#include "heap.h" +#include "menu.h" +#include "message.h" +#include "narc.h" +#include "network_icon.h" +#include "overlay_manager.h" +#include "palette.h" +#include "pokemon_icon.h" +#include "render_oam.h" +#include "render_text.h" +#include "render_window.h" +#include "screen_fade.h" +#include "sound_playback.h" +#include "sprite_system.h" +#include "string_gf.h" +#include "sys_task.h" +#include "sys_task_manager.h" +#include "system.h" +#include "text.h" +#include "unk_02014A84.h" +#include "vram_transfer.h" + +#include "res/fonts/pl_font.naix" +#include "res/graphics/mail/mail.naix" +#include "res/graphics/windows/pl_winframe.naix" +#include "res/pokemon/pl_poke_icon.naix" +#include "res/text/bank/mail.h" + +#define MAIL_SENTENCE_WINDOW_WIDTH 26 +#define MAIL_SENTENCE_WINDOW_HEIGHT 4 + +#define MAIL_CONFIRM_CANCEL_WINDOW_WIDTH 8 +#define MAIL_CONFIRM_CANCEL_WINDOW_HEIGHT 2 + +#define MAIL_OPTION_PALETTE_SLOT_START 34 + +#define BASE_TILE_MAIL_SENTENCE_WINDOW_1 (1023 - MAIL_SENTENCE_WINDOW_WIDTH * MAIL_SENTENCE_WINDOW_HEIGHT) +#define BASE_TILE_MAIL_SENTENCE_WINDOW_2 (BASE_TILE_MAIL_SENTENCE_WINDOW_1 - MAIL_SENTENCE_WINDOW_WIDTH * MAIL_SENTENCE_WINDOW_HEIGHT) +#define BASE_TILE_MAIL_SENTENCE_WINDOW_3 (BASE_TILE_MAIL_SENTENCE_WINDOW_2 - MAIL_SENTENCE_WINDOW_WIDTH * MAIL_SENTENCE_WINDOW_HEIGHT) +#define BASE_TILE_MAIL_CONFIRM_WINDOW (BASE_TILE_MAIL_SENTENCE_WINDOW_3 - MAIL_CONFIRM_CANCEL_WINDOW_WIDTH * MAIL_CONFIRM_CANCEL_WINDOW_HEIGHT) +#define BASE_TILE_MAIL_CANCEL_WINDOW (BASE_TILE_MAIL_CONFIRM_WINDOW - MAIL_CONFIRM_CANCEL_WINDOW_WIDTH * MAIL_CONFIRM_CANCEL_WINDOW_HEIGHT) +#define BASE_TILE_MAIL_MESSAGE_WINDOW (BASE_TILE_MAIL_CANCEL_WINDOW - MAIL_CONFIRM_CANCEL_WINDOW_WIDTH * MAIL_CONFIRM_CANCEL_WINDOW_HEIGHT) +#define BASE_TILE_MAIL_YES_NO_MENU (BASE_TILE_MAIL_MESSAGE_WINDOW - MESSAGE_WINDOW_TILE_COUNT) + +enum MailViewerMode { + MAIL_VIEWER_MODE_READ = 0, + MAIL_VIEWER_MODE_WRITE, + MAIL_VIEWER_MODE_CONFIRM_EMPTY, + MAIL_VIEWER_MODE_CANCEL, +}; + +enum MailViewerState { + MAIL_VIEWER_STATE_INIT = 0, + MAIL_VIEWER_STATE_INIT_GRAPHICS, + MAIL_VIEWER_STATE_FADE_IN, + MAIL_VIEWER_STATE_MAIN, + MAIL_VIEWER_STATE_FADE_OUT, + MAIL_VIEWER_STATE_EXIT, +}; + +enum MailViewerWindow { + MAIL_VIEWER_WINDOW_SENTENCE_1 = 0, + MAIL_VIEWER_WINDOW_SENTENCE_2, + MAIL_VIEWER_WINDOW_SENTENCE_3, + MAIL_VIEWER_WINDOW_CONFIRM, + MAIL_VIEWER_WINDOW_CANCEL, + MAIL_VIEWER_WINDOW_MESSAGE, + MAIL_VIEWER_WINDOW_COUNT, +}; + +enum VerticalSelectionIndex { + SELECTION_INDEX_SENTENCE_1 = 0, + SELECTION_INDEX_SENTENCE_2, + SELECTION_INDEX_SENTENCE_3, + SELECTION_INDEX_CONFIRM_CANCEL, + VERTICAL_SELECTION_INDEX_COUNT, +}; + +typedef struct MailViewerApp { + enum HeapID heapID; + int state; + u16 subState; + u16 frame; + u8 mode; + u8 initialMode; + u8 padding; + u8 printerID; + u8 textFrameDelay; + u8 verticalSelectionIndex; + u8 horizontalSelectionIndex; + u8 pauseGlowEffect; + u8 blendFraction; + u8 blendDirection; + u8 blendIndex; + u8 prevBlendIndex; + BgConfig *bgConfig; + MailViewerAppArgs *args; + MessageLoader *loader; + void *dummy[1]; + u8 padding2[8]; + PaletteData *paletteData; + void *backgroundNSCRBuffer; + void *interfaceNSCRBuffer; + NNSG2dScreenData *backgroundScreenData; + NNSG2dScreenData *interfaceScreenData; + Window windows[MAIL_VIEWER_WINDOW_COUNT]; + Menu *yesNoMenu; + SpriteSystem *spriteSys; + SpriteManager *spriteMan; + ManagedSprite *managedSprites[MAIL_MAX_ICONS]; +} MailViewerApp; + +typedef BOOL (*MailViewerModeFunc)(MailViewerApp *mailViewerApp); + +static BOOL Main(MailViewerApp *mailViewerApp); +static BOOL MailViewer_InitGraphics(MailViewerApp *mailViewerApp); +static BOOL MailViewer_FreeResources(MailViewerApp *mailViewerApp); +static void MailViewer_VBlankCallback(void *data); +static void MailViewer_InitBackgrounds(MailViewerApp *mailViewerApp); +static void MailViewer_TeardownBgs(MailViewerApp *mailViewerApp); +static void MailViewer_DrawMail(MailViewerApp *mailViewerApp); +static void MailViewer_FreeAssets(MailViewerApp *mailViewerApp); +static void MailViewer_AddWindows(MailViewerApp *mailViewerApp); +static void MailViewer_RemoveWindows(MailViewerApp *mailViewerApp); +static void MailViewer_PrintText(MailViewerApp *mailViewerApp); +static void MailViewer_InitSprites(MailViewerApp *mailViewerApp); +static void MailViewer_FreeSprites(MailViewerApp *mailViewerApp); + +int gDummy; // necessary for matching + +BOOL MailViewer_Init(ApplicationManager *appMan, int *state) +{ + MailViewerApp *mailViewerApp = (MailViewerApp *)ApplicationManager_Data(appMan); + + Heap_Create(HEAP_ID_APPLICATION, HEAP_ID_MAIL_VIEWER, HEAP_SIZE_MAIL_VIEWER); + mailViewerApp = ApplicationManager_NewData(appMan, sizeof(MailViewerApp), HEAP_ID_MAIL_VIEWER); + memset(mailViewerApp, 0, sizeof(MailViewerApp)); + + mailViewerApp->heapID = HEAP_ID_MAIL_VIEWER; + + mailViewerApp->args = (MailViewerAppArgs *)ApplicationManager_Args(appMan); + mailViewerApp->initialMode = mailViewerApp->mode = mailViewerApp->args->writeMode; + mailViewerApp->verticalSelectionIndex = mailViewerApp->args->sentenceIndex; + mailViewerApp->horizontalSelectionIndex = mailViewerApp->args->horizontalSelectionIndex; + mailViewerApp->prevBlendIndex = mailViewerApp->blendIndex = mailViewerApp->verticalSelectionIndex; + mailViewerApp->args->result = MAIL_VIEWER_RESULT_CANCEL; + mailViewerApp->textFrameDelay = Options_TextFrameDelay(mailViewerApp->args->options); + mailViewerApp->frame = Options_Frame(mailViewerApp->args->options); + + RenderControlFlags_SetCanABSpeedUpPrint(TRUE); + return TRUE; +} + +BOOL MailViewer_Main(ApplicationManager *appMan, int *state) +{ + MailViewerApp *mailViewerApp = (MailViewerApp *)ApplicationManager_Data(appMan); + + return !!Main(mailViewerApp); +} + +BOOL MailViewer_Exit(ApplicationManager *appMan, int *state) +{ + MailViewerApp *mailViewerApp = (MailViewerApp *)ApplicationManager_Data(appMan); + + RenderControlFlags_SetCanABSpeedUpPrint(FALSE); + + int heapID = mailViewerApp->heapID; + + ApplicationManager_FreeData(appMan); + Heap_Destroy(heapID); + + return TRUE; +} + +static BOOL MailViewer_AreSentencesEmpty(MailViewerApp *mailViewerApp) +{ + for (int i = 0; i < MAIL_MAX_SENTENCES; i++) { + if (Sentence_IsValid(&mailViewerApp->args->sentences[i])) { + return FALSE; + } + } + + return TRUE; +} + +static BOOL MailViewer_HandleInput_Read(MailViewerApp *unused) +{ + if (JOY_NEW(PAD_BUTTON_A | PAD_BUTTON_B)) { + Sound_PlayEffect(SEQ_SE_DP_PIRORIRO2); + return TRUE; + } + + return FALSE; +} + +static BOOL MailViewer_HandleInput_Write(MailViewerApp *mailViewerApp) +{ + BOOL selectionChanged = FALSE; + + if (JOY_NEW(PAD_BUTTON_A)) { + if (mailViewerApp->verticalSelectionIndex == SELECTION_INDEX_CONFIRM_CANCEL) { + if (mailViewerApp->horizontalSelectionIndex == 0) { + if (MailViewer_AreSentencesEmpty(mailViewerApp)) { + Sound_PlayEffect(SEQ_SE_DP_DECIDE); + mailViewerApp->mode = MAIL_VIEWER_MODE_CONFIRM_EMPTY; + return FALSE; + } else { + mailViewerApp->args->result = MAIL_VIEWER_RESULT_CONFIRM; + Sound_PlayEffect(SEQ_SE_DP_PIRORIRO2); + } + } else { + Sound_PlayEffect(SEQ_SE_DP_DECIDE); + mailViewerApp->mode = MAIL_VIEWER_MODE_CANCEL; + return FALSE; + } + + mailViewerApp->args->sentenceIndex = mailViewerApp->args->horizontalSelectionIndex = 0; + } else { + mailViewerApp->args->result = mailViewerApp->args->sentenceIndex = mailViewerApp->verticalSelectionIndex; + mailViewerApp->args->horizontalSelectionIndex = mailViewerApp->horizontalSelectionIndex; + Sound_PlayEffect(SEQ_SE_DP_DECIDE); + } + + return TRUE; + } else if (JOY_NEW(PAD_BUTTON_B)) { + Sound_PlayEffect(SEQ_SE_DP_DECIDE); + mailViewerApp->mode = MAIL_VIEWER_MODE_CANCEL; + return FALSE; + } + + if (JOY_NEW(PAD_BUTTON_START)) { + mailViewerApp->verticalSelectionIndex = SELECTION_INDEX_CONFIRM_CANCEL; + mailViewerApp->horizontalSelectionIndex = 0; + selectionChanged = TRUE; + } else if (JOY_NEW(PAD_KEY_DOWN)) { + mailViewerApp->verticalSelectionIndex = (mailViewerApp->verticalSelectionIndex + 1) % VERTICAL_SELECTION_INDEX_COUNT; + selectionChanged = TRUE; + } else if (JOY_NEW(PAD_KEY_UP)) { + mailViewerApp->verticalSelectionIndex = (mailViewerApp->verticalSelectionIndex + VERTICAL_SELECTION_INDEX_COUNT - 1) % VERTICAL_SELECTION_INDEX_COUNT; + selectionChanged = TRUE; + } else if (JOY_NEW(PAD_KEY_RIGHT | PAD_KEY_LEFT)) { + if (mailViewerApp->verticalSelectionIndex == SELECTION_INDEX_CONFIRM_CANCEL) { + mailViewerApp->horizontalSelectionIndex ^= 1; + selectionChanged = TRUE; + } + } else { + return FALSE; + } + + if (!selectionChanged) { + return FALSE; + } + + Sound_PlayEffect(SEQ_SE_CONFIRM); + + if (mailViewerApp->verticalSelectionIndex == SELECTION_INDEX_CONFIRM_CANCEL) { + mailViewerApp->blendIndex = mailViewerApp->verticalSelectionIndex + mailViewerApp->horizontalSelectionIndex; + } else { + mailViewerApp->blendIndex = mailViewerApp->verticalSelectionIndex; + } + + return FALSE; +} + +static BOOL MailViewer_HandleConfirmEmpty(MailViewerApp *mailViewerApp) +{ + switch (mailViewerApp->subState) { + case 0: + Window_DrawMessageBoxWithScrollCursor(&mailViewerApp->windows[MAIL_VIEWER_WINDOW_MESSAGE], TRUE, 1 + STANDARD_WINDOW_TILE_COUNT, 6); + Window_FillTilemap(&(mailViewerApp->windows[MAIL_VIEWER_WINDOW_MESSAGE]), PIXEL_FILL(15)); + + String *string = String_Init(38 * 2, mailViewerApp->heapID); + + MessageLoader_GetString(mailViewerApp->loader, Mail_Text_EnterPhraseOrWord, string); + Text_AddPrinterWithParamsAndColor(&mailViewerApp->windows[MAIL_VIEWER_WINDOW_MESSAGE], FONT_MESSAGE, string, 0, 0, TEXT_SPEED_INSTANT, TEXT_COLOR(1, 2, 15), NULL); + String_Free(string); + break; + case 1: + if (!JOY_NEW(PAD_BUTTON_A | PAD_BUTTON_B)) { + return FALSE; + } + + Window_EraseMessageBox(&mailViewerApp->windows[MAIL_VIEWER_WINDOW_MESSAGE], TRUE); + Window_ClearAndCopyToVRAM(&mailViewerApp->windows[MAIL_VIEWER_WINDOW_MESSAGE]); + + mailViewerApp->subState = 0; + mailViewerApp->mode = mailViewerApp->initialMode; + + return FALSE; + } + + mailViewerApp->subState++; + return FALSE; +} + +static void MailViewer_OpenYesNoMenu(MailViewerApp *mailViewerApp) +{ + static const WindowTemplate template = { + .bgLayer = BG_LAYER_MAIN_0, + .tilemapLeft = 25, + .tilemapTop = 13, + .width = YES_NO_MENU_TILE_W, + .height = YES_NO_MENU_TILE_H, + .palette = 3, + .baseTile = BASE_TILE_MAIL_YES_NO_MENU, + }; + + mailViewerApp->yesNoMenu = Menu_MakeYesNoChoice(mailViewerApp->bgConfig, &template, 1, 5, mailViewerApp->heapID); +} + +static int MailViewer_CheckYesNoMenuInput(MailViewerApp *mailViewerApp) +{ + switch (Menu_ProcessInputAndHandleExit(mailViewerApp->yesNoMenu, mailViewerApp->heapID)) { + case MENU_YES: + return 1; + case MENU_CANCEL: + return 0; + } + + return -1; +} + +static BOOL MailViewer_HandleCancel(MailViewerApp *mailViewerApp) +{ + switch (mailViewerApp->subState) { + case 0: + mailViewerApp->pauseGlowEffect = TRUE; + + Window_DrawMessageBoxWithScrollCursor(&mailViewerApp->windows[MAIL_VIEWER_WINDOW_MESSAGE], TRUE, 1 + STANDARD_WINDOW_TILE_COUNT, 6); + Window_FillTilemap(&(mailViewerApp->windows[MAIL_VIEWER_WINDOW_MESSAGE]), PIXEL_FILL(15)); + + String *string = String_Init(38 * 2, mailViewerApp->heapID); + MessageLoader_GetString(mailViewerApp->loader, Mail_Text_StopGivingMailPrompt, string); + mailViewerApp->printerID = Text_AddPrinterWithParamsAndColor(&mailViewerApp->windows[MAIL_VIEWER_WINDOW_MESSAGE], FONT_MESSAGE, string, 0, 0, mailViewerApp->textFrameDelay, TEXT_COLOR(1, 2, 15), NULL); + + String_Free(string); + PaletteData_Blend(mailViewerApp->paletteData, PLTTBUF_MAIN_BG, MAIL_OPTION_PALETTE_SLOT_START + mailViewerApp->prevBlendIndex, 1, 0, COLOR_WHITE); + + mailViewerApp->prevBlendIndex = mailViewerApp->blendIndex; + mailViewerApp->blendDirection = 0; + mailViewerApp->blendFraction = 0; + break; + case 1: + if (Text_IsPrinterActive(mailViewerApp->printerID)) { + return FALSE; + } + + MailViewer_OpenYesNoMenu(mailViewerApp); + break; + case 2: + int result = MailViewer_CheckYesNoMenuInput(mailViewerApp); + + if (result < 0) { + return FALSE; + } + + Window_EraseMessageBox(&mailViewerApp->windows[MAIL_VIEWER_WINDOW_MESSAGE], TRUE); + Window_ClearAndCopyToVRAM(&(mailViewerApp->windows[MAIL_VIEWER_WINDOW_MESSAGE])); + mailViewerApp->subState = 0; + + if (result) { + mailViewerApp->args->result = MAIL_VIEWER_RESULT_CANCEL; + return TRUE; + } else { + mailViewerApp->mode = mailViewerApp->initialMode; + mailViewerApp->pauseGlowEffect = FALSE; + return FALSE; + } + } + + mailViewerApp->subState++; + return FALSE; +} + +static BOOL Main(MailViewerApp *mailViewerApp) +{ + switch (mailViewerApp->state) { + case MAIL_VIEWER_STATE_INIT: + SetVBlankCallback(NULL, NULL); + DisableHBlank(); + GXLayers_DisableEngineALayers(); + GXLayers_DisableEngineBLayers(); + + GX_SetVisiblePlane(0); + GXS_SetVisiblePlane(0); + + SetScreenColorBrightness(DS_SCREEN_MAIN, COLOR_BLACK); + SetScreenColorBrightness(DS_SCREEN_SUB, COLOR_BLACK); + ResetVisibleHardwareWindows(DS_SCREEN_MAIN); + ResetVisibleHardwareWindows(DS_SCREEN_SUB); + break; + case MAIL_VIEWER_STATE_INIT_GRAPHICS: + if (!MailViewer_InitGraphics(mailViewerApp)) { + return FALSE; + } + + SetVBlankCallback(MailViewer_VBlankCallback, mailViewerApp); + GXLayers_EngineAToggleLayers(GX_PLANEMASK_OBJ, TRUE); + ResetScreenMasterBrightness(DS_SCREEN_MAIN); + + G2_SetBlendAlpha(GX_BLEND_PLANEMASK_BG2, GX_BLEND_PLANEMASK_BG3, 28, 4); + + PaletteData_StartFade(mailViewerApp->paletteData, PLTTBUF_MAIN_BG_F | PLTTBUF_MAIN_OBJ_F, 0xFFFF, -1, 16, 0, 0x0); + break; + case MAIL_VIEWER_STATE_FADE_IN: + if (mailViewerApp->spriteMan != NULL) { + SpriteSystem_DrawSprites(mailViewerApp->spriteMan); + } + + if (PaletteData_GetSelectedBuffersMask(mailViewerApp->paletteData)) { + return FALSE; + } + break; + case MAIL_VIEWER_STATE_MAIN: + static const MailViewerModeFunc funcs[] = { + [MAIL_VIEWER_MODE_READ] = MailViewer_HandleInput_Read, + [MAIL_VIEWER_MODE_WRITE] = MailViewer_HandleInput_Write, + [MAIL_VIEWER_MODE_CONFIRM_EMPTY] = MailViewer_HandleConfirmEmpty, + [MAIL_VIEWER_MODE_CANCEL] = MailViewer_HandleCancel, + }; + + if (mailViewerApp->spriteMan != NULL) { + SpriteSystem_DrawSprites(mailViewerApp->spriteMan); + } + + if (!funcs[mailViewerApp->mode](mailViewerApp)) { + return FALSE; + } + + PaletteData_StartFade(mailViewerApp->paletteData, PLTTBUF_MAIN_BG_F | PLTTBUF_MAIN_OBJ_F, 0xFFFF, -1, 0, 16, 0x0); + break; + case MAIL_VIEWER_STATE_FADE_OUT: + if (PaletteData_GetSelectedBuffersMask(mailViewerApp->paletteData)) { + if (mailViewerApp->spriteMan != NULL) { + SpriteSystem_DrawSprites(mailViewerApp->spriteMan); + } + + return FALSE; + } + + SetScreenColorBrightness(DS_SCREEN_MAIN, COLOR_BLACK); + SetScreenColorBrightness(DS_SCREEN_SUB, COLOR_BLACK); + SetVBlankCallback(NULL, NULL); + GXLayers_DisableEngineALayers(); + GXLayers_DisableEngineBLayers(); + + GX_SetVisiblePlane(0); + GXS_SetVisiblePlane(0); + break; + case MAIL_VIEWER_STATE_EXIT: + if (MailViewer_FreeResources(mailViewerApp)) { + return TRUE; + } + + return FALSE; + } + + mailViewerApp->state++; + return FALSE; +} + +static void MailViewer_VBlankCallback(void *data) +{ + MailViewerApp *mailViewerApp = (MailViewerApp *)data; + + if (mailViewerApp->paletteData != NULL) { + PaletteData_CommitFadedBuffers(mailViewerApp->paletteData); + } + + if (mailViewerApp->spriteSys != NULL) { + SpriteSystem_TransferOam(); + } + + NNS_GfdDoVramTransfer(); + Bg_RunScheduledUpdates(mailViewerApp->bgConfig); + + OS_SetIrqCheckFlag(OS_IE_V_BLANK); +} + +static void MailViewer_SelectedGlowEffectTask(SysTask *sysTask, void *data) +{ + MailViewerApp *mailViewerApp = (MailViewerApp *)data; + + if (mailViewerApp->paletteData == NULL) { + SysTask_Done(sysTask); + return; + } + + if (mailViewerApp->pauseGlowEffect) { + return; + } + + if (mailViewerApp->prevBlendIndex != mailViewerApp->blendIndex) { + PaletteData_Blend(mailViewerApp->paletteData, PLTTBUF_MAIN_BG, MAIL_OPTION_PALETTE_SLOT_START + mailViewerApp->prevBlendIndex, 1, 0, COLOR_WHITE); + mailViewerApp->prevBlendIndex = mailViewerApp->blendIndex; + mailViewerApp->blendDirection = 0; + mailViewerApp->blendFraction = 0; + } + + PaletteData_Blend(mailViewerApp->paletteData, PLTTBUF_MAIN_BG, MAIL_OPTION_PALETTE_SLOT_START + mailViewerApp->blendIndex, 1, mailViewerApp->blendFraction, COLOR_WHITE); + + if (mailViewerApp->blendDirection) { + if (mailViewerApp->blendFraction-- == 1) { + mailViewerApp->blendDirection ^= 1; + } + } else { + if (mailViewerApp->blendFraction++ == 12) { + mailViewerApp->blendDirection ^= 1; + } + } +} + +static BOOL MailViewer_InitGraphics(MailViewerApp *mailViewerApp) +{ + switch (mailViewerApp->subState) { + case 0: + MailViewer_InitBackgrounds(mailViewerApp); + break; + case 1: + MailViewer_DrawMail(mailViewerApp); + break; + case 2: + MailViewer_AddWindows(mailViewerApp); + MailViewer_PrintText(mailViewerApp); + break; + case 3: + MailViewer_InitSprites(mailViewerApp); + mailViewerApp->subState = 0; + return TRUE; + } + + mailViewerApp->subState++; + return FALSE; +} + +static BOOL MailViewer_FreeResources(MailViewerApp *mailViewerApp) +{ + MailViewer_FreeSprites(mailViewerApp); + + // bug: dummy is never initialized + // heap is destroyed soon after this so memory shouldn't leak + if (mailViewerApp->dummy != NULL) { + MessageLoader_Free(mailViewerApp->loader); + } + + MailViewer_RemoveWindows(mailViewerApp); + MailViewer_FreeAssets(mailViewerApp); + MailViewer_TeardownBgs(mailViewerApp); + + return TRUE; +} + +static void MailViewer_SetVRAMBanks(void) +{ + GXBanks banks = { + GX_VRAM_BG_128_A, + GX_VRAM_BGEXTPLTT_NONE, + GX_VRAM_SUB_BG_128_C, + GX_VRAM_SUB_BGEXTPLTT_NONE, + GX_VRAM_OBJ_64_E, + GX_VRAM_OBJEXTPLTT_NONE, + GX_VRAM_SUB_OBJ_16_I, + GX_VRAM_SUB_OBJEXTPLTT_NONE, + GX_VRAM_TEX_NONE, + GX_VRAM_TEXPLTT_NONE + }; + + GXLayers_SetBanks(&banks); +} + +static void MailViewer_InitBackgrounds(MailViewerApp *mailViewerApp) +{ + MailViewer_SetVRAMBanks(); + + mailViewerApp->bgConfig = BgConfig_New(mailViewerApp->heapID); + + GraphicsModes graphicsModes = { + .displayMode = GX_DISPMODE_GRAPHICS, + .mainBgMode = GX_BGMODE_0, + .subBgMode = GX_BGMODE_0, + .bg0As2DOr3D = GX_BG0_AS_2D + }; + + SetAllGraphicsModes(&graphicsModes); + + BgTemplate bgTemplates[] = { + { + .x = 0, + .y = 0, + .bufferSize = 0x800, + .baseTile = 0, + .screenSize = BG_SCREEN_SIZE_256x256, + .colorMode = GX_BG_COLORMODE_16, + .screenBase = GX_BG_SCRBASE_0xf800, + .charBase = GX_BG_CHARBASE_0x10000, + .bgExtPltt = GX_BG_EXTPLTT_01, + .priority = 0, + .areaOver = 0, + .mosaic = FALSE, + }, + { + .x = 0, + .y = 0, + .bufferSize = 0x800, + .baseTile = 0, + .screenSize = BG_SCREEN_SIZE_256x256, + .colorMode = GX_BG_COLORMODE_16, + .screenBase = GX_BG_SCRBASE_0xf000, + .charBase = GX_BG_CHARBASE_0x00000, + .bgExtPltt = GX_BG_EXTPLTT_01, + .priority = 1, + .areaOver = 0, + .mosaic = FALSE, + }, + { + .x = 0, + .y = 0, + .bufferSize = 0x800, + .baseTile = 0, + .screenSize = BG_SCREEN_SIZE_256x256, + .colorMode = GX_BG_COLORMODE_16, + .screenBase = GX_BG_SCRBASE_0xe800, + .charBase = GX_BG_CHARBASE_0x00000, + .bgExtPltt = GX_BG_EXTPLTT_01, + .priority = 2, + .areaOver = 0, + .mosaic = FALSE, + }, + { + .x = 0, + .y = 0, + .bufferSize = 0x800, + .baseTile = 0, + .screenSize = BG_SCREEN_SIZE_256x256, + .colorMode = GX_BG_COLORMODE_16, + .screenBase = GX_BG_SCRBASE_0xe000, + .charBase = GX_BG_CHARBASE_0x00000, + .bgExtPltt = GX_BG_EXTPLTT_01, + .priority = 3, + .areaOver = 0, + .mosaic = FALSE, + }, + { + .x = 0, + .y = 0, + .bufferSize = 0x800, + .baseTile = 0, + .screenSize = BG_SCREEN_SIZE_256x256, + .colorMode = GX_BG_COLORMODE_16, + .screenBase = GX_BG_SCRBASE_0xf800, + .charBase = GX_BG_CHARBASE_0x00000, + .bgExtPltt = GX_BG_EXTPLTT_01, + .priority = 0, + .areaOver = 0, + .mosaic = FALSE, + }, + }; + + Bg_InitFromTemplate(mailViewerApp->bgConfig, BG_LAYER_MAIN_0, &bgTemplates[0], BG_TYPE_STATIC); + Bg_InitFromTemplate(mailViewerApp->bgConfig, BG_LAYER_MAIN_1, &bgTemplates[1], BG_TYPE_STATIC); + Bg_InitFromTemplate(mailViewerApp->bgConfig, BG_LAYER_MAIN_2, &bgTemplates[2], BG_TYPE_STATIC); + Bg_InitFromTemplate(mailViewerApp->bgConfig, BG_LAYER_MAIN_3, &bgTemplates[3], BG_TYPE_STATIC); + Bg_InitFromTemplate(mailViewerApp->bgConfig, BG_LAYER_SUB_0, &bgTemplates[4], BG_TYPE_STATIC); + + Bg_ClearTilemap(mailViewerApp->bgConfig, BG_LAYER_MAIN_0); + Bg_ClearTilemap(mailViewerApp->bgConfig, BG_LAYER_MAIN_1); + Bg_ClearTilemap(mailViewerApp->bgConfig, BG_LAYER_MAIN_2); + Bg_ClearTilemap(mailViewerApp->bgConfig, BG_LAYER_MAIN_3); + Bg_ClearTilemap(mailViewerApp->bgConfig, BG_LAYER_SUB_0); + Bg_ClearTilesRange(BG_LAYER_MAIN_0, TILE_SIZE_4BPP, 0, mailViewerApp->heapID); + Bg_ClearTilesRange(BG_LAYER_MAIN_1, TILE_SIZE_4BPP, 0, mailViewerApp->heapID); + Bg_ClearTilesRange(BG_LAYER_MAIN_2, TILE_SIZE_4BPP, 0, mailViewerApp->heapID); + Bg_ClearTilesRange(BG_LAYER_MAIN_3, TILE_SIZE_4BPP, 0, mailViewerApp->heapID); + Bg_ClearTilesRange(BG_LAYER_SUB_0, TILE_SIZE_4BPP, 0, mailViewerApp->heapID); +} + +static void MailViewer_TeardownBgs(MailViewerApp *mailViewerApp) +{ + Bg_FreeTilemapBuffer(mailViewerApp->bgConfig, BG_LAYER_SUB_0); + Bg_FreeTilemapBuffer(mailViewerApp->bgConfig, BG_LAYER_MAIN_3); + Bg_FreeTilemapBuffer(mailViewerApp->bgConfig, BG_LAYER_MAIN_2); + Bg_FreeTilemapBuffer(mailViewerApp->bgConfig, BG_LAYER_MAIN_1); + Bg_FreeTilemapBuffer(mailViewerApp->bgConfig, BG_LAYER_MAIN_0); + Heap_Free(mailViewerApp->bgConfig); +} + +static void MailViewer_DrawMail(MailViewerApp *mailViewerApp) +{ + NNSG2dCharacterData *charData; + NNSG2dPaletteData *plttData; + int tilesNarcIndex = grass_mail_tiles_NCGR + mailViewerApp->args->mailType; + int screenDataNarcIndex = grass_mail_NSCR + mailViewerApp->args->mailType; + int plttNarcIndex = grass_mail_tiles_NCLR + mailViewerApp->args->mailType; + NARC *narc = NARC_ctor(NARC_INDEX_GRAPHIC__MAIL_GRA, mailViewerApp->heapID); + + LoadStandardWindowGraphics(mailViewerApp->bgConfig, BG_LAYER_MAIN_0, 1, 5, STANDARD_WINDOW_SYSTEM, mailViewerApp->heapID); + LoadMessageBoxGraphics(mailViewerApp->bgConfig, BG_LAYER_MAIN_0, 1 + STANDARD_WINDOW_TILE_COUNT, 6, mailViewerApp->frame, mailViewerApp->heapID); + + u32 size = NARC_GetMemberSize(narc, tilesNarcIndex); + void *narcMemberBuffer = Heap_AllocAtEnd(mailViewerApp->heapID, size); + NARC_ReadWholeMember(narc, tilesNarcIndex, (void *)narcMemberBuffer); + + NNS_G2dGetUnpackedCharacterData(narcMemberBuffer, &charData); + Bg_LoadTiles(mailViewerApp->bgConfig, BG_LAYER_MAIN_1, charData->pRawData, charData->szByte, 0); + Bg_LoadTiles(mailViewerApp->bgConfig, BG_LAYER_SUB_0, charData->pRawData, charData->szByte, 0); + Heap_Free(narcMemberBuffer); + + size = NARC_GetMemberSize(narc, plttNarcIndex); + narcMemberBuffer = Heap_AllocAtEnd(mailViewerApp->heapID, size); + NARC_ReadWholeMember(narc, plttNarcIndex, (void *)narcMemberBuffer); + + NNS_G2dGetUnpackedPaletteData(narcMemberBuffer, &plttData); + Bg_LoadPalette(BG_LAYER_SUB_0, plttData->pRawData, plttData->szByte, 0); + + mailViewerApp->paletteData = PaletteData_New(mailViewerApp->heapID); + + PaletteData_AllocBuffer(mailViewerApp->paletteData, PLTTBUF_MAIN_BG, PALETTE_SIZE_BYTES * 7, mailViewerApp->heapID); + PaletteData_AllocBuffer(mailViewerApp->paletteData, PLTTBUF_MAIN_OBJ, PALETTE_SIZE_BYTES * 3, mailViewerApp->heapID); + PaletteData_LoadBuffer(mailViewerApp->paletteData, plttData->pRawData, PLTTBUF_MAIN_BG, 0, PALETTE_SIZE_BYTES * 3); + + if (mailViewerApp->mode == MAIL_VIEWER_MODE_WRITE) { + PaletteData_LoadBuffer(mailViewerApp->paletteData, &((u16 *)plttData->pRawData)[PLTT_OFFSET(3) / sizeof(u16)], PLTTBUF_MAIN_BG, PLTT_OFFSET(1) / sizeof(u16), PALETTE_SIZE_BYTES); + } + + PaletteData_LoadBufferFromFileStart(mailViewerApp->paletteData, NARC_INDEX_POKETOOL__ICONGRA__PL_POKE_ICON, shared_pals_NCLR, mailViewerApp->heapID, PLTTBUF_MAIN_OBJ, PALETTE_SIZE_BYTES * 3, 0); + PaletteData_LoadBufferFromFileStart(mailViewerApp->paletteData, NARC_INDEX_GRAPHIC__PL_FONT, font_NCLR, mailViewerApp->heapID, PLTTBUF_MAIN_BG, PALETTE_SIZE_BYTES, (PALETTE_SIZE_BYTES / sizeof(u16)) * 3); + PaletteData_LoadBufferFromFileStart(mailViewerApp->paletteData, NARC_INDEX_GRAPHIC__PL_FONT, screen_indicators_NCLR, mailViewerApp->heapID, PLTTBUF_MAIN_BG, PALETTE_SIZE_BYTES, (PALETTE_SIZE_BYTES / sizeof(u16)) * 4); + PaletteData_LoadBufferFromFileStart(mailViewerApp->paletteData, NARC_INDEX_GRAPHIC__PL_WINFRAME, standard_system_NCLR, mailViewerApp->heapID, PLTTBUF_MAIN_BG, PALETTE_SIZE_BYTES, (PALETTE_SIZE_BYTES / sizeof(u16)) * 5); + PaletteData_LoadBufferFromFileStart(mailViewerApp->paletteData, NARC_INDEX_GRAPHIC__PL_WINFRAME, message_box_00_NCLR + mailViewerApp->frame, mailViewerApp->heapID, PLTTBUF_MAIN_BG, PALETTE_SIZE_BYTES, (PALETTE_SIZE_BYTES / sizeof(u16)) * 6); + PaletteData_Blend(mailViewerApp->paletteData, PLTTBUF_MAIN_BG, 0, (PALETTE_SIZE_BYTES / sizeof(u16)) * 7, 16, COLOR_BLACK); + PaletteData_Blend(mailViewerApp->paletteData, PLTTBUF_MAIN_OBJ, 0, (PALETTE_SIZE_BYTES / sizeof(u16)) * 3, 16, COLOR_BLACK); + PaletteData_SetAutoTransparent(mailViewerApp->paletteData, TRUE); + PaletteData_CommitFadedBuffers(mailViewerApp->paletteData); + Heap_Free(narcMemberBuffer); + + size = NARC_GetMemberSize(narc, screenDataNarcIndex); + mailViewerApp->backgroundNSCRBuffer = Heap_Alloc(mailViewerApp->heapID, size); + NARC_ReadWholeMember(narc, screenDataNarcIndex, (void *)mailViewerApp->backgroundNSCRBuffer); + NNS_G2dGetUnpackedScreenData(mailViewerApp->backgroundNSCRBuffer, &mailViewerApp->backgroundScreenData); + + size = NARC_GetMemberSize(narc, interface_NSCR); + mailViewerApp->interfaceNSCRBuffer = Heap_Alloc(mailViewerApp->heapID, size); + NARC_ReadWholeMember(narc, interface_NSCR, (void *)mailViewerApp->interfaceNSCRBuffer); + NNS_G2dGetUnpackedScreenData(mailViewerApp->interfaceNSCRBuffer, &mailViewerApp->interfaceScreenData); + + NARC_dtor(narc); + Bg_FillTilemapRect(mailViewerApp->bgConfig, BG_LAYER_SUB_0, TILEMAP_PALETTE_SHIFT(2) | 1, 0, 0, SCREEN_WIDTH_TILES, 32, TILEMAP_FILL_VAL_INCLUDES_PALETTE); + Bg_CopyToTilemapRect(mailViewerApp->bgConfig, BG_LAYER_MAIN_3, 0, 0, SCREEN_WIDTH_TILES, SCREEN_HEIGHT_TILES, mailViewerApp->backgroundScreenData->rawData, 0, 0, mailViewerApp->backgroundScreenData->screenWidth / TILE_WIDTH_PIXELS, mailViewerApp->backgroundScreenData->screenHeight / TILE_HEIGHT_PIXELS); + Bg_ScheduleTilemapTransfer(mailViewerApp->bgConfig, BG_LAYER_MAIN_3); + Bg_ScheduleTilemapTransfer(mailViewerApp->bgConfig, BG_LAYER_SUB_0); + + if (mailViewerApp->mode == MAIL_VIEWER_MODE_WRITE) { + Bg_CopyToTilemapRect(mailViewerApp->bgConfig, BG_LAYER_MAIN_2, 0, 0, SCREEN_WIDTH_TILES, SCREEN_HEIGHT_TILES, mailViewerApp->interfaceScreenData->rawData, 0, 0, mailViewerApp->interfaceScreenData->screenWidth / TILE_WIDTH_PIXELS, mailViewerApp->interfaceScreenData->screenHeight / TILE_HEIGHT_PIXELS); + Bg_ScheduleTilemapTransfer(mailViewerApp->bgConfig, BG_LAYER_MAIN_2); + + mailViewerApp->blendFraction = 0; + mailViewerApp->blendDirection = 0; + + SysTask_Start(MailViewer_SelectedGlowEffectTask, mailViewerApp, 0); + } +} + +static void MailViewer_FreeAssets(MailViewerApp *mailViewerApp) +{ + Heap_Free(mailViewerApp->interfaceNSCRBuffer); + Heap_Free(mailViewerApp->backgroundNSCRBuffer); + PaletteData_FreeBuffer(mailViewerApp->paletteData, PLTTBUF_MAIN_OBJ); + PaletteData_FreeBuffer(mailViewerApp->paletteData, PLTTBUF_MAIN_BG); + PaletteData_Free(mailViewerApp->paletteData); + + mailViewerApp->paletteData = NULL; + + G2_SetBlendAlpha(GX_BLEND_PLANEMASK_NONE, GX_BLEND_PLANEMASK_NONE, 31, 0); +} + +static void MailViewer_AddWindows(MailViewerApp *mailViewerApp) +{ + Window_Add(mailViewerApp->bgConfig, &mailViewerApp->windows[MAIL_VIEWER_WINDOW_SENTENCE_1], BG_LAYER_MAIN_1, 3, 3, MAIL_SENTENCE_WINDOW_WIDTH, MAIL_SENTENCE_WINDOW_HEIGHT, 1, BASE_TILE_MAIL_SENTENCE_WINDOW_1); + Window_Add(mailViewerApp->bgConfig, &mailViewerApp->windows[MAIL_VIEWER_WINDOW_SENTENCE_2], BG_LAYER_MAIN_1, 3, 3 + MAIL_SENTENCE_WINDOW_HEIGHT + 1, MAIL_SENTENCE_WINDOW_WIDTH, MAIL_SENTENCE_WINDOW_HEIGHT, 1, BASE_TILE_MAIL_SENTENCE_WINDOW_2); + Window_Add(mailViewerApp->bgConfig, &mailViewerApp->windows[MAIL_VIEWER_WINDOW_SENTENCE_3], BG_LAYER_MAIN_1, 3, 3 + (MAIL_SENTENCE_WINDOW_HEIGHT + 1) * 2, MAIL_SENTENCE_WINDOW_WIDTH, MAIL_SENTENCE_WINDOW_HEIGHT, 1, BASE_TILE_MAIL_SENTENCE_WINDOW_3); + Window_Add(mailViewerApp->bgConfig, &mailViewerApp->windows[MAIL_VIEWER_WINDOW_CONFIRM], BG_LAYER_MAIN_1, 21, 20, MAIL_CONFIRM_CANCEL_WINDOW_WIDTH, MAIL_CONFIRM_CANCEL_WINDOW_HEIGHT, 1, BASE_TILE_MAIL_CONFIRM_WINDOW); + Window_Add(mailViewerApp->bgConfig, &mailViewerApp->windows[MAIL_VIEWER_WINDOW_CANCEL], BG_LAYER_MAIN_1, 3, 20, MAIL_CONFIRM_CANCEL_WINDOW_WIDTH, MAIL_CONFIRM_CANCEL_WINDOW_HEIGHT, 1, BASE_TILE_MAIL_CANCEL_WINDOW); + Window_Add(mailViewerApp->bgConfig, &mailViewerApp->windows[MAIL_VIEWER_WINDOW_MESSAGE], BG_LAYER_MAIN_0, 2, 19, MESSAGE_WINDOW_TILE_W, MESSAGE_WINDOW_TILE_H, 4, BASE_TILE_MAIL_MESSAGE_WINDOW); + + for (int i = 0; i < MAIL_VIEWER_WINDOW_COUNT; i++) { + Window_FillTilemap(&(mailViewerApp->windows[i]), 0); + + if (i < MAIL_VIEWER_WINDOW_MESSAGE) { + Window_CopyToVRAM(&mailViewerApp->windows[i]); + } + } +} + +static void MailViewer_RemoveWindows(MailViewerApp *mailViewerApp) +{ + for (int i = 0; i < MAIL_VIEWER_WINDOW_COUNT; i++) { + Window_ClearAndCopyToVRAM(&mailViewerApp->windows[i]); + Window_Remove(&mailViewerApp->windows[i]); + } +} + +static void MailViewer_PrintText(MailViewerApp *mailViewerApp) +{ + for (int i = 0; i < MAIL_MAX_SENTENCES; i++) { + if (!Sentence_IsValid(&mailViewerApp->args->sentences[i])) { + continue; + } + + String *sentenceStr = Sentence_AsString(&mailViewerApp->args->sentences[i], mailViewerApp->heapID); + + Text_AddPrinterWithParamsAndColor(&mailViewerApp->windows[i], FONT_MESSAGE, sentenceStr, 0, 0, TEXT_SPEED_INSTANT, TEXT_COLOR(1, 2, 0), NULL); + String_Free(sentenceStr); + Window_CopyToVRAM(&mailViewerApp->windows[i]); + } + + if (mailViewerApp->mode == MAIL_VIEWER_MODE_WRITE) { + mailViewerApp->loader = MessageLoader_Init(MSG_LOADER_LOAD_ON_DEMAND, NARC_INDEX_MSGDATA__PL_MSG, TEXT_BANK_MAIL, mailViewerApp->heapID); + + String *string = String_Init(8 * 2, mailViewerApp->heapID); + + for (int i = 0; i < 2; i++) { + String_Clear(string); + MessageLoader_GetString(mailViewerApp->loader, Mail_Text_Confirm + i, string); + + int xOffset = 8 * TILE_WIDTH_PIXELS - Font_CalcStringWidth(FONT_MESSAGE, string, 0); + xOffset /= 2; + + Text_AddPrinterWithParamsAndColor(&mailViewerApp->windows[MAIL_VIEWER_WINDOW_CONFIRM + i], FONT_MESSAGE, string, xOffset, 2, TEXT_SPEED_INSTANT, TEXT_COLOR(1, 2, 0), NULL); + Window_CopyToVRAM(&mailViewerApp->windows[MAIL_VIEWER_WINDOW_CONFIRM + i]); + } + + String_Free(string); + } else { + Text_AddPrinterWithParamsAndColor(&mailViewerApp->windows[MAIL_VIEWER_WINDOW_CONFIRM], FONT_MESSAGE, mailViewerApp->args->trainerName, 0, 2, TEXT_SPEED_INSTANT, TEXT_COLOR(1, 2, 0), NULL); + Window_CopyToVRAM(&mailViewerApp->windows[MAIL_VIEWER_WINDOW_CONFIRM]); + } +} + +static void MailViewer_InitSprites(MailViewerApp *mailViewerApp) +{ + SpriteTemplate spriteTemplate; + + NetworkIcon_InitIfConnected(); + + if (mailViewerApp->mode == MAIL_VIEWER_MODE_WRITE) { + return; + } + + VramTransfer_New(32, mailViewerApp->heapID); + + mailViewerApp->spriteSys = SpriteSystem_Alloc(mailViewerApp->heapID); + mailViewerApp->spriteMan = SpriteManager_New(mailViewerApp->spriteSys); + + RenderOamTemplate oamTemplate = { + .mainOamStart = 0, + .mainOamCount = 7, + .mainAffineOamStart = 1, + .mainAffineOamCount = 1, + .subOamStart = 0, + .subOamCount = 1, + .subAffineOamStart = 1, + .subAffineOamCount = 1, + }; + + CharTransferTemplateWithModes transferTemplate = { + .maxTasks = 3, + .sizeMain = 1024, + .sizeSub = 0, + .modeMain = GX_OBJVRAMMODE_CHAR_1D_32K, + .modeSub = GX_OBJVRAMMODE_CHAR_1D_32K, + }; + + const SpriteResourceCapacities capacities = { + .asStruct = { + .charCapacity = 3, + .plttCapacity = 1, + .cellCapacity = 1, + .animCapacity = 1, + .mcellCapacity = 0, + .manimCapacity = 0, + } + }; + + SpriteSystem_Init(mailViewerApp->spriteSys, &oamTemplate, &transferTemplate, 32); + SpriteSystem_InitSprites(mailViewerApp->spriteSys, mailViewerApp->spriteMan, 3); + SpriteSystem_InitManagerWithCapacities(mailViewerApp->spriteSys, mailViewerApp->spriteMan, &capacities); + RenderOam_ClearMain(mailViewerApp->heapID); + + SpriteSystem_LoadPlttResObj(mailViewerApp->spriteSys, mailViewerApp->spriteMan, NARC_INDEX_POKETOOL__ICONGRA__PL_POKE_ICON, PokeIconPalettesFileIndex(), FALSE, 3, NNS_G2D_VRAM_TYPE_2DMAIN, 0); + SpriteSystem_LoadCellResObj(mailViewerApp->spriteSys, mailViewerApp->spriteMan, NARC_INDEX_POKETOOL__ICONGRA__PL_POKE_ICON, PokeIconCellsFileIndex(), FALSE, 0); + SpriteSystem_LoadAnimResObj(mailViewerApp->spriteSys, mailViewerApp->spriteMan, NARC_INDEX_POKETOOL__ICONGRA__PL_POKE_ICON, PokeIconAnimationFileIndex(), FALSE, 0); + + for (int i = 0; i < MAIL_MAX_ICONS; i++) { + if (mailViewerApp->args->iconData[i].asValue == MAIL_MON_ICON_NONE) { + break; + } + + SpriteSystem_LoadCharResObjWithHardwareMappingType(mailViewerApp->spriteSys, mailViewerApp->spriteMan, NARC_INDEX_POKETOOL__ICONGRA__PL_POKE_ICON, mailViewerApp->args->iconData[i].asStruct.spriteIndex, FALSE, NNS_G2D_VRAM_TYPE_2DMAIN, i); + MI_CpuClear8(&spriteTemplate, sizeof(SpriteTemplate)); + + spriteTemplate.x = 128 - 40 * i; + spriteTemplate.y = 160; + spriteTemplate.z = 0; + + spriteTemplate.animIdx = 0; + spriteTemplate.bgPriority = 2; + spriteTemplate.plttIdx = mailViewerApp->args->iconData[i].asStruct.palIndex; + spriteTemplate.vramTransfer = FALSE; + spriteTemplate.vramType = NNS_G2D_VRAM_TYPE_2DMAIN; + + spriteTemplate.resources[SPRITE_RESOURCE_CHAR] = i; + spriteTemplate.resources[SPRITE_RESOURCE_PLTT] = 0; + spriteTemplate.resources[SPRITE_RESOURCE_CELL] = 0; + spriteTemplate.resources[SPRITE_RESOURCE_ANIM] = 0; + spriteTemplate.resources[SPRITE_RESOURCE_MULTI_CELL] = SPRITE_RESOURCE_NONE; + spriteTemplate.resources[SPRITE_RESOURCE_MULTI_ANIM] = SPRITE_RESOURCE_NONE; + + mailViewerApp->managedSprites[i] = SpriteSystem_NewSprite(mailViewerApp->spriteSys, mailViewerApp->spriteMan, &spriteTemplate); + + if (mailViewerApp->args->iconData[i].asStruct.spriteIndex == icon_00000_NCGR) { + ManagedSprite_SetDrawFlag(mailViewerApp->managedSprites[i], FALSE); + } + } +} + +static void MailViewer_FreeSprites(MailViewerApp *mailViewerApp) +{ + if (mailViewerApp->mode == MAIL_VIEWER_MODE_READ) { + for (int i = 0; i < MAIL_MAX_ICONS; i++) { + if (mailViewerApp->managedSprites[i] != NULL) { + Sprite_DeleteAndFreeResources(mailViewerApp->managedSprites[i]); + } + } + + SpriteSystem_FreeResourcesAndManager(mailViewerApp->spriteSys, mailViewerApp->spriteMan); + SpriteSystem_Free(mailViewerApp->spriteSys); + VramTransfer_Free(); + } +} diff --git a/src/applications/party_menu/main.c b/src/applications/party_menu/main.c index 78264aa8c0..07b8bfbd26 100644 --- a/src/applications/party_menu/main.c +++ b/src/applications/party_menu/main.c @@ -2771,7 +2771,7 @@ static int ProcessItemApplication(PartyMenuApplication *application) switch (CheckItemUsageValidity(application)) { case 0: if (Item_IsMail(application->partyMenu->usedItemID) == TRUE) { - application->partyMenu->menuSelectionResult = PARTY_MENU_EXIT_CODE_MAIL; + application->partyMenu->menuSelectionResult = PARTY_MENU_EXIT_CODE_WRITE_MAIL; return PARTY_MENU_STATE_32; } @@ -2906,7 +2906,7 @@ static int ProcessPokemonItemSwap(PartyMenuApplication *application) if (Item_IsMail(application->partyMenu->usedItemID) == 1) { Bag_TryRemoveItem(application->partyMenu->bag, (u16)v5, 1, HEAP_ID_PARTY_MENU); SwapPokemonItem(application, mon, v4, v5); - application->partyMenu->menuSelectionResult = PARTY_MENU_EXIT_CODE_MAIL; + application->partyMenu->menuSelectionResult = PARTY_MENU_EXIT_CODE_WRITE_MAIL; return PARTY_MENU_STATE_32; } diff --git a/src/applications/party_menu/unk_02083370.c b/src/applications/party_menu/unk_02083370.c index dcbf345715..0b2c9ea968 100644 --- a/src/applications/party_menu/unk_02083370.c +++ b/src/applications/party_menu/unk_02083370.c @@ -5,6 +5,7 @@ #include "generated/items.h" +#include "applications/mail.h" #include "applications/party_menu/defs.h" #include "applications/party_menu/form_change.h" #include "applications/party_menu/main.h" @@ -29,7 +30,6 @@ #include "string_template.h" #include "system.h" #include "text.h" -#include "unk_02097624.h" #include "res/text/bank/party_menu.h" @@ -310,7 +310,7 @@ static int sub_0208384C(void *applicationPtr) application = applicationPtr; v1 = Party_GetPokemonBySlotIndex(application->partyMenu->party, application->currPartySlot); - if (sub_02097788(application->partyMenu->mailbox, v1, HEAP_ID_PARTY_MENU) != 0xFFFFFFFF) { + if (Mail_TransferFromMonToMailbox(application->partyMenu->mailbox, v1, HEAP_ID_PARTY_MENU) != 0xFFFFFFFF) { application->partyMembers[application->currPartySlot].heldItem = ITEM_NONE; PartyMenu_DrawMemberHeldItem(application, application->currPartySlot, application->partyMembers[application->currPartySlot].heldItem); PartyMenu_PrintLongMessage(application, PartyMenu_Text_MailWasSentToYourPC, FALSE); diff --git a/src/battle/battle_system.c b/src/battle/battle_system.c index 5a7ed406de..e3ecdaa6a2 100644 --- a/src/battle/battle_system.c +++ b/src/battle/battle_system.c @@ -1606,9 +1606,9 @@ u8 BattleMessage_PrintTrainerMessage(BattleSystem *battleSys, int trainerID, int String *string; if (msgType == TRMSG_WIN) { - string = sub_02014B34(&battleSys->trainers[battler].winMsg, HEAP_ID_BATTLE); + string = Sentence_AsString(&battleSys->trainers[battler].winMsg, HEAP_ID_BATTLE); } else { - string = sub_02014B34(&battleSys->trainers[battler].loseMsg, HEAP_ID_BATTLE); + string = Sentence_AsString(&battleSys->trainers[battler].loseMsg, HEAP_ID_BATTLE); } Window_FillTilemap(window, 0xFF); diff --git a/src/daycare_save.c b/src/daycare_save.c index b032c94df6..06d044d2f6 100644 --- a/src/daycare_save.c +++ b/src/daycare_save.c @@ -6,8 +6,7 @@ #include "constants/charcode.h" #include "constants/daycare.h" -#include "struct_defs/mail.h" - +#include "mail.h" #include "pokemon.h" #include "savedata.h" diff --git a/src/evolution.c b/src/evolution.c index c075f40d1c..5902a56368 100644 --- a/src/evolution.c +++ b/src/evolution.c @@ -10,7 +10,6 @@ #include "generated/species.h" #include "generated/trainer_score_events.h" -#include "struct_defs/mail.h" #include "struct_defs/seal_case.h" #include "struct_defs/sprite_animation_frame.h" #include "struct_defs/struct_0207C894.h" diff --git a/src/game_records.c b/src/game_records.c index cd81928ad7..8034a1336f 100644 --- a/src/game_records.c +++ b/src/game_records.c @@ -132,7 +132,7 @@ static u8 sUsesHighLimit[MAX_RECORDS] = { [RECORD_UNK_042] = FALSE, [RECORD_UNK_043] = FALSE, [RECORD_UNK_044] = FALSE, - [RECORD_UNK_045] = FALSE, + [RECORD_TIMES_MAIL_WRITTEN] = FALSE, [RECORD_UNK_046] = FALSE, [RECORD_SPHERES_BURIED] = FALSE, [RECORD_WATCHED_TV] = FALSE, @@ -260,7 +260,7 @@ static u32 GetRecordLimit(int id) static const u16 sTrainerScoreIncrements[MAX_TRAINER_SCORE_EVENTS] = { [TRAINER_SCORE_EVENT_BERRY_HARVESTED] = 1, [TRAINER_SCORE_EVENT_HONEY_USED] = 1, - [TRAINER_SCORE_EVENT_UNK_02] = 1, + [TRAINER_SCORE_EVENT_MAIL_WRITTEN] = 1, [TRAINER_SCORE_EVENT_TV_INTERVIEW_GIVEN] = 1, [TRAINER_SCORE_EVENT_SIGNED_TRAINER_CARD] = 1, [TRAINER_SCORE_EVENT_UNK_05] = 1, diff --git a/src/item.c b/src/item.c index 8c8bd7be1f..4645496fdd 100644 --- a/src/item.c +++ b/src/item.c @@ -3328,7 +3328,7 @@ u8 Item_TMHMNumber(u16 item) u8 Item_IsMail(u16 item) { - for (u32 i = 0; i < NUM_MAILS; i++) { + for (u32 i = 0; i < NUM_MAIL_TYPES; i++) { if (sMailItemIDs[i] == item) { return TRUE; } @@ -3337,9 +3337,9 @@ u8 Item_IsMail(u16 item) return FALSE; } -u8 Item_MailNumber(u16 item) +u8 Item_GetMailType(u16 item) { - for (u32 i = 0; i < NUM_MAILS; i++) { + for (u32 i = 0; i < NUM_MAIL_TYPES; i++) { if (sMailItemIDs[i] == item) { return i; } @@ -3348,13 +3348,13 @@ u8 Item_MailNumber(u16 item) return ITEM_NONE; } -u16 Item_ForMailNumber(u8 mail) +u16 Item_ForMailType(u8 mailType) { - if (mail >= NUM_MAILS) { + if (mailType >= NUM_MAIL_TYPES) { return ITEM_NONE; } - return sMailItemIDs[mail]; + return sMailItemIDs[mailType]; } u8 Item_IsBerry(u16 item) diff --git a/src/item_use_functions.c b/src/item_use_functions.c index 71a5d80c05..3cefcf38d6 100644 --- a/src/item_use_functions.c +++ b/src/item_use_functions.c @@ -7,8 +7,8 @@ #include "constants/savedata/vars_flags.h" #include "struct_decls/map_object.h" -#include "struct_defs/struct_02097728.h" +#include "applications/mail.h" #include "applications/party_menu/defs.h" #include "applications/party_menu/main.h" #include "applications/poffin_case/main.h" @@ -551,10 +551,10 @@ static void UseMailFromMenu(ItemMenuUseContext *usageContext, const ItemUseConte { FieldSystem *fieldSystem = FieldTask_GetFieldSystem(usageContext->fieldTask); StartMenu *menu = FieldTask_GetEnv(usageContext->fieldTask); - UnkStruct_02097728 *v2 = sub_0203D94C(fieldSystem, 3, Item_MailNumber(usageContext->item), HEAP_ID_FIELD2); + MailAppArgs *args = FieldSystem_LaunchMailApp_Read(fieldSystem, MAIL_CONTEXT_CHECK, Item_GetMailType(usageContext->item), HEAP_ID_FIELD2); - menu->additionalTaskContext = sub_0203C540(usageContext->item, 3, 0); - menu->taskData = v2; + menu->additionalTaskContext = StartMenu_BuildMailData(usageContext->item, MAIL_READ_FROM_BAG, 0); + menu->taskData = args; StartMenu_SetCallback(menu, StartMenu_ExitMail); } diff --git a/src/mail.c b/src/mail.c index 5baceb609e..45b3089283 100644 --- a/src/mail.c +++ b/src/mail.c @@ -1,16 +1,12 @@ #include "mail.h" #include -#include #include "constants/forms.h" #include "constants/items.h" #include "generated/genders.h" #include "generated/species.h" -#include "struct_defs/mail.h" -#include "struct_defs/union_02028328.h" - #include "charcode_util.h" #include "heap.h" #include "party.h" @@ -21,52 +17,54 @@ #include "trainer_info.h" #include "unk_02014A84.h" -static int Mail_GetEmptySlotInArray_(Mail *array, int arraySize); -static int Mail_GetEmptySlotCountInArray(Mail *array, int arraySize); -static Mail *Mailbox_GetMailFromSlot(Mailbox *mailbox, int param1, int slot); +#include "res/pokemon/pl_poke_icon.naix" +#include "res/pokemon/species_icon_palettes.h" + +#define IconTilesIndex(icon) (icon + icon_00000_NCGR) + +static int Mail_GetEmptySlot(Mail array[], int arraySize); +static int Mail_CountValidMail(Mail array[], int arraySize); +static Mail *GetMailAtMailboxSlot(Mailbox *mailbox, enum MailContext context, int slot); static const struct { - u16 unk_00; - u16 unk_02; + u16 baseSpriteIndex; + u16 formSpriteIndex; u16 species; u8 form; - u8 unk_07; -} Unk_020E5B0C[] = { - { 0x1EE, 0x21C, SPECIES_GIRATINA, GIRATINA_FORM_ORIGIN }, - { 0x1F3, 0x21D, SPECIES_SHAYMIN, SHAYMIN_FORM_SKY }, - { 0x1E6, 0x21E, SPECIES_ROTOM, ROTOM_FORM_HEAT }, - { 0x1E6, 0x21F, SPECIES_ROTOM, ROTOM_FORM_WASH }, - { 0x1E6, 0x220, SPECIES_ROTOM, ROTOM_FORM_FROST }, - { 0x1E6, 0x221, SPECIES_ROTOM, ROTOM_FORM_FAN }, - { 0x1E6, 0x222, SPECIES_ROTOM, ROTOM_FORM_MOW } +} sPlatExclusiveFormData[] = { + { .baseSpriteIndex = IconTilesIndex(SPECIES_GIRATINA), .formSpriteIndex = IconTilesIndex(ICON_GIRATINA_ORIGIN), .species = SPECIES_GIRATINA, .form = GIRATINA_FORM_ORIGIN }, + { .baseSpriteIndex = IconTilesIndex(SPECIES_SHAYMIN), .formSpriteIndex = IconTilesIndex(ICON_SHAYMIN_SKY), .species = SPECIES_SHAYMIN, .form = SHAYMIN_FORM_SKY }, + { .baseSpriteIndex = IconTilesIndex(SPECIES_ROTOM), .formSpriteIndex = IconTilesIndex(ICON_ROTOM_HEAT), .species = SPECIES_ROTOM, .form = ROTOM_FORM_HEAT }, + { .baseSpriteIndex = IconTilesIndex(SPECIES_ROTOM), .formSpriteIndex = IconTilesIndex(ICON_ROTOM_WASH), .species = SPECIES_ROTOM, .form = ROTOM_FORM_WASH }, + { .baseSpriteIndex = IconTilesIndex(SPECIES_ROTOM), .formSpriteIndex = IconTilesIndex(ICON_ROTOM_FROST), .species = SPECIES_ROTOM, .form = ROTOM_FORM_FROST }, + { .baseSpriteIndex = IconTilesIndex(SPECIES_ROTOM), .formSpriteIndex = IconTilesIndex(ICON_ROTOM_FAN), .species = SPECIES_ROTOM, .form = ROTOM_FORM_FAN }, + { .baseSpriteIndex = IconTilesIndex(SPECIES_ROTOM), .formSpriteIndex = IconTilesIndex(ICON_ROTOM_MOW), .species = SPECIES_ROTOM, .form = ROTOM_FORM_MOW } }; -void Mail_Init(Mail *mail) +void Mail_Reset(Mail *mail) { - int i; - mail->trainerID = 0; mail->trainerGender = GENDER_MALE; mail->language = gGameLanguage; mail->gameVersion = gGameVersion; - mail->mailType = 0xFFFF; + mail->mailType = MAIL_TYPE_NONE; - CharCode_FillWithEOS(mail->trainerName, 8); + CharCode_FillWithEOS(mail->trainerName, TRAINER_NAME_LEN + 1); - for (i = 0; i < 3; i++) { - mail->unk_18[i].val2 = 0xFFFF; + for (int i = 0; i < MAIL_MAX_ICONS; i++) { + mail->iconData[i].asValue = MAIL_MON_ICON_NONE; } - mail->unk_1E = 0; + mail->platExclusiveFormIcons = 0; - for (i = 0; i < 3; i++) { - sub_02014A84(&mail->unk_20[i]); + for (int i = 0; i < MAIL_MAX_SENTENCES; i++) { + Sentence_Init(&mail->sentences[i]); } } -BOOL Mail_IsEmpty(Mail *mail) +BOOL Mail_IsValid(Mail *mail) { - if ((mail->mailType >= 0) && (mail->mailType <= 11)) { + if (0 <= mail->mailType && mail->mailType <= NUM_MAIL_TYPES - 1) { return TRUE; } @@ -76,7 +74,7 @@ BOOL Mail_IsEmpty(Mail *mail) Mail *Mail_New(enum HeapID heapID) { Mail *mail = Heap_AllocAtEnd(heapID, sizeof(Mail)); - Mail_Init(mail); + Mail_Reset(mail); return mail; } @@ -86,49 +84,45 @@ void Mail_Copy(Mail *src, Mail *dest) MI_CpuCopy8(src, dest, sizeof(Mail)); } -void sub_020281AC(Mail *mail, u8 mailType, u8 param2, SaveData *saveData) +void Mail_SetTrainerAndIconData(Mail *mail, u8 mailType, u8 selectedPartySlot, SaveData *saveData) { - u8 i, v1, palIndex, j; - u16 species; - u32 spriteIndex, isEgg, form; - TrainerInfo *trainerInfo; - Pokemon *mon; + u32 isEgg; - Mail_Init(mail); + Mail_Reset(mail); mail->mailType = mailType; Party *party = SaveData_GetParty(saveData); - trainerInfo = SaveData_GetTrainerInfo(saveData); + TrainerInfo *trainerInfo = SaveData_GetTrainerInfo(saveData); CharCode_Copy(mail->trainerName, TrainerInfo_Name(trainerInfo)); - mail->trainerGender = (u8)TrainerInfo_Gender(trainerInfo); + mail->trainerGender = TrainerInfo_Gender(trainerInfo); mail->trainerID = TrainerInfo_ID(trainerInfo); - mail->unk_1E = 0; + mail->platExclusiveFormIcons = 0; - for (i = param2, v1 = 0; i < Party_GetCurrentCount(party); i++) { - mon = Party_GetPokemonBySlotIndex(party, i); - species = Pokemon_GetValue(mon, MON_DATA_SPECIES, NULL); + for (u8 slot = selectedPartySlot, i = 0; slot < Party_GetCurrentCount(party); slot++) { + Pokemon *mon = Party_GetPokemonBySlotIndex(party, slot); + u16 species = Pokemon_GetValue(mon, MON_DATA_SPECIES, NULL); isEgg = Pokemon_GetValue(mon, MON_DATA_IS_EGG, NULL); - form = Pokemon_GetValue(mon, MON_DATA_FORM, NULL); - spriteIndex = Pokemon_IconSpriteIndex(mon); - palIndex = PokeIconPaletteIndex(species, form, isEgg); + u32 form = Pokemon_GetValue(mon, MON_DATA_FORM, NULL); + u32 spriteIndex = Pokemon_IconSpriteIndex(mon); + u8 palIndex = PokeIconPaletteIndex(species, form, isEgg); - mail->unk_18[v1].val1_0 = (u16)spriteIndex; - mail->unk_18[v1].val1_12 = palIndex; + mail->iconData[i].asStruct.spriteIndex = spriteIndex; + mail->iconData[i].asStruct.palIndex = palIndex; - for (j = 0; j < NELEMS(Unk_020E5B0C); j++) { - if ((Unk_020E5B0C[j].unk_02 == mail->unk_18[v1].val1_0) && (Unk_020E5B0C[j].form == form)) { - mail->unk_18[v1].val1_0 = Unk_020E5B0C[j].unk_00; - mail->unk_18[v1].val1_12 = PokeIconPaletteIndex(species, 0, isEgg); - mail->unk_1E |= Unk_020E5B0C[j].form << (v1 * 5); + for (u8 j = 0; j < NELEMS(sPlatExclusiveFormData); j++) { + if (sPlatExclusiveFormData[j].formSpriteIndex == mail->iconData[i].asStruct.spriteIndex && sPlatExclusiveFormData[j].form == form) { + mail->iconData[i].asStruct.spriteIndex = sPlatExclusiveFormData[j].baseSpriteIndex; + mail->iconData[i].asStruct.palIndex = PokeIconPaletteIndex(species, 0, isEgg); + mail->platExclusiveFormIcons |= sPlatExclusiveFormData[j].form << (i * 5); break; } } - v1++; + i++; - if (v1 >= 3) { + if (i >= MAIL_MAX_ICONS) { break; } } @@ -139,9 +133,9 @@ u32 Mail_GetTrainerID(const Mail *mail) return mail->trainerID; } -u16 *Mail_GetTrainerName(Mail *mail) +charcode_t *Mail_GetTrainerName(Mail *mail) { - return &(mail->trainerName[0]); + return &mail->trainerName[0]; } u8 Mail_GetTrainerGender(const Mail *mail) @@ -156,7 +150,7 @@ u8 Mail_GetMailType(const Mail *mail) void Mail_SetMailType(Mail *mail, const u8 mailType) { - if (mailType >= NUM_MAILS) { + if (mailType >= NUM_MAIL_TYPES) { return; } @@ -173,62 +167,59 @@ u8 Mail_GetGameVersion(const Mail *mail) return mail->gameVersion; } -u16 sub_02028328(const Mail *mail, u8 param1, u8 param2, u16 param3) +u16 Mail_GetIconData(const Mail *mail, u8 index, enum MailIconDataType type, u16 platExclusiveFormIcons) { - UnkUnion_02028328 v0; - int i; + if (index < MAIL_MAX_ICONS) { + MailIconData iconData = mail->iconData[index]; - if (param1 < 3) { - v0 = mail->unk_18[param1]; - - for (i = 0; i < NELEMS(Unk_020E5B0C); i++) { - if ((Unk_020E5B0C[i].unk_00 == v0.val1_0) && (Unk_020E5B0C[i].form == ((param3 >> (param1 * 5)) & 0x1f))) { - v0.val1_0 = Unk_020E5B0C[i].unk_02; - v0.val1_12 = PokeIconPaletteIndex(Unk_020E5B0C[i].species, Unk_020E5B0C[i].form, FALSE); + for (int i = 0; i < NELEMS(sPlatExclusiveFormData); i++) { + if (sPlatExclusiveFormData[i].baseSpriteIndex == iconData.asStruct.spriteIndex && sPlatExclusiveFormData[i].form == ((platExclusiveFormIcons >> (index * 5)) & 0x1F)) { + iconData.asStruct.spriteIndex = sPlatExclusiveFormData[i].formSpriteIndex; + iconData.asStruct.palIndex = PokeIconPaletteIndex(sPlatExclusiveFormData[i].species, sPlatExclusiveFormData[i].form, FALSE); break; } } - if (v0.val1_0 > 546) { - v0.val1_0 = 7; - v0.val1_12 = 0; + if (iconData.asStruct.spriteIndex > IconTilesIndex(ICON_ROTOM_MOW)) { + iconData.asStruct.spriteIndex = icon_00000_NCGR; + iconData.asStruct.palIndex = 0; } - switch (param2) { - case 0: - return v0.val1_0; - case 1: - return v0.val1_12; - case 2: + switch (type) { + case ICON_DATA_SPRITE_INDEX: + return iconData.asStruct.spriteIndex; + case ICON_DATA_PLTT_INDEX: + return iconData.asStruct.palIndex; + case ICON_DATA_VALUE: default: - return v0.val2; + return iconData.asValue; } } else { return 0; } } -u16 sub_02028408(const Mail *param0) +u16 Mail_GetPlatExclusiveFormIcons(const Mail *mail) { - return param0->unk_1E; + return mail->platExclusiveFormIcons; } -Sentence *sub_0202840C(Mail *param0, u8 param1) +Sentence *Mail_GetSentence(Mail *mail, u8 index) { - if (param1 < 3) { - return &(param0->unk_20[param1]); + if (index < MAIL_MAX_SENTENCES) { + return &mail->sentences[index]; } else { - return &(param0->unk_20[0]); + return &mail->sentences[0]; } } -void sub_0202841C(Mail *param0, Sentence *param1, u8 param2) +void Mail_SetSentence(Mail *mail, Sentence *sentence, u8 index) { - if (param2 >= 3) { + if (index >= MAIL_MAX_SENTENCES) { return; } - sub_02014CC0(¶m0->unk_20[param2], param1); + Sentence_Set(&mail->sentences[index], sentence); } Mailbox *SaveData_GetMailbox(SaveData *saveData) @@ -243,98 +234,87 @@ int Mailbox_SaveSize(void) void Mailbox_Init(Mailbox *mailbox) { - int i = 0; - - for (i = 0; i < MAILBOX_SIZE; i++) { - Mail_Init(&mailbox->mail[i]); + for (int i = 0; i < MAILBOX_SIZE; i++) { + Mail_Reset(&mailbox->mail[i]); } } -int Mail_GetEmptySlotInArray(Mailbox *mailbox, int param1) +int Mail_GetEmptyMailSlot(Mailbox *mailbox, enum MailContext context) { - switch (param1) { - case 0: - return Mail_GetEmptySlotInArray_(mailbox->mail, MAILBOX_SIZE); - default: - return 0xFFFFFFFF; + if (context == MAIL_CONTEXT_MAILBOX) { + return Mail_GetEmptySlot(mailbox->mail, MAILBOX_SIZE); + } else { + return -1; } - - return 0xFFFFFFFF; } -void sub_02028470(Mailbox *mailbox, int param1, int slot) +void Mailbox_ClearMailAtSlot(Mailbox *mailbox, enum MailContext context, int slot) { - Mail *mail = Mailbox_GetMailFromSlot(mailbox, param1, slot); + Mail *mail = GetMailAtMailboxSlot(mailbox, context, slot); if (mail != NULL) { - Mail_Init(mail); + Mail_Reset(mail); } } -void Mailbox_CopyMailToSlot(Mailbox *mailbox, int param1, int slot, Mail *src) +void Mailbox_CopyMailToSlot(Mailbox *mailbox, enum MailContext context, int slot, Mail *src) { - Mail *dest = Mailbox_GetMailFromSlot(mailbox, param1, slot); + Mail *dest = GetMailAtMailboxSlot(mailbox, context, slot); if (dest != NULL) { Mail_Copy(src, dest); } } -int sub_02028494(Mailbox *mailbox, int param1) +int Mailbox_CountMail(Mailbox *mailbox, enum MailContext context) { - switch (param1) { - case 0: - return Mail_GetEmptySlotCountInArray(mailbox->mail, MAILBOX_SIZE); - default: + if (context == MAIL_CONTEXT_MAILBOX) { + return Mail_CountValidMail(mailbox->mail, MAILBOX_SIZE); + } else { return 0; } - - return 0; } -Mail *sub_020284A8(Mailbox *mailbox, int param1, int slot, enum HeapID heapID) +Mail *Mailbox_CopyMailAtSlot(Mailbox *mailbox, enum MailContext context, int slot, enum HeapID heapID) { - Mail *v0 = Mailbox_GetMailFromSlot(mailbox, param1, slot); - Mail *v1 = Mail_New(heapID); + Mail *mail = GetMailAtMailboxSlot(mailbox, context, slot); + Mail *ret = Mail_New(heapID); - if (v0 != NULL) { - Mail_Copy(v0, v1); + if (mail != NULL) { + Mail_Copy(mail, ret); } - return v1; + return ret; } -void sub_020284CC(Mailbox *mailbox, int param1, int param2, Mail *param3) +void Mailbox_GetMailAtSlot(Mailbox *mailbox, enum MailContext context, int slot, Mail *out) { - Mail *v0 = Mailbox_GetMailFromSlot(mailbox, param1, param2); + Mail *mail = GetMailAtMailboxSlot(mailbox, context, slot); - if (v0 == NULL) { - Mail_Init(param3); + if (mail == NULL) { + Mail_Reset(out); } else { - Mail_Copy(v0, param3); + Mail_Copy(mail, out); } } -static int Mail_GetEmptySlotInArray_(Mail *array, int arraySize) +static int Mail_GetEmptySlot(Mail array[], int arraySize) { - int i = 0; - - for (i = 0; i < arraySize; i++) { - if (!Mail_IsEmpty(&array[i])) { + for (int i = 0; i < arraySize; i++) { + if (!Mail_IsValid(&array[i])) { return i; } } - return 0xFFFFFFFF; + return -1; } -static int Mail_GetEmptySlotCountInArray(Mail *array, int arraySize) +static int Mail_CountValidMail(Mail array[], int arraySize) { - int i = 0; int count = 0; - for (i = 0; i < arraySize; i++) { - if (Mail_IsEmpty(&array[i])) { + for (int i = 0; i < arraySize; i++) { + if (Mail_IsValid(&array[i])) { count++; } } @@ -342,19 +322,12 @@ static int Mail_GetEmptySlotCountInArray(Mail *array, int arraySize) return count; } -static Mail *Mailbox_GetMailFromSlot(Mailbox *mailbox, int param1, int slot) +static Mail *GetMailAtMailboxSlot(Mailbox *mailbox, enum MailContext context, int slot) { Mail *mail = NULL; - switch (param1) { - case 0: - if (slot < MAILBOX_SIZE) { - mail = &(mailbox->mail[slot]); - } - - break; - default: - break; + if (context == MAIL_CONTEXT_MAILBOX && slot < MAILBOX_SIZE) { + mail = &mailbox->mail[slot]; } return mail; diff --git a/src/meson.build b/src/meson.build index 166c2f7268..abe24171f1 100644 --- a/src/meson.build +++ b/src/meson.build @@ -318,7 +318,7 @@ pokeplatinum_c = files( 'unk_020972FC.c', 'berry_data.c', 'unk_0209747C.c', - 'unk_02097624.c', + 'applications/mail.c', 'unk_02097B18.c', 'egg_hatch.c', 'unk_020985E4.c', @@ -800,7 +800,7 @@ pokeplatinum_c = files( 'applications/rowan_intro/rowan_intro_app.c', 'applications/rowan_intro/tv_app.c', 'applications/options_menu.c', - 'overlay075/ov75_021D0D80.c', + 'applications/mail_viewer.c', 'overlay076/ov76_0223B140.c', 'overlay076/ov76_0223B870.c', 'overlay076/ov76_0223D338.c', diff --git a/src/overlay005/script_message.c b/src/overlay005/script_message.c index c6f5342e58..333b062963 100644 --- a/src/overlay005/script_message.c +++ b/src/overlay005/script_message.c @@ -149,12 +149,12 @@ static void GetStringFromSentence(ScriptMessage *msgData, u16 sentenceType, u16 Sentence sentence; String *string; - sub_02014A84(&sentence); + Sentence_Init(&sentence); sub_02014CE0(&sentence, sentenceType, sentenceID); Sentence_SetWord(&sentence, 0, word1); Sentence_SetWord(&sentence, 1, word2); - string = sub_02014B34(&sentence, HEAP_ID_FIELD3); + string = Sentence_AsString(&sentence, HEAP_ID_FIELD3); String_Copy(msgData->msgBuf, string); String_Free(string); diff --git a/src/overlay020/ov20_021D0D80.c b/src/overlay020/ov20_021D0D80.c index cadb4232f4..eeb6abcded 100644 --- a/src/overlay020/ov20_021D0D80.c +++ b/src/overlay020/ov20_021D0D80.c @@ -3,7 +3,6 @@ #include #include -#include "struct_decls/struct_0209747C_decl.h" #include "struct_decls/struct_020998EC_decl.h" #include "struct_defs/sentence.h" diff --git a/src/overlay056/ov56_022561C0.c b/src/overlay056/ov56_022561C0.c index fe054a37ce..6cac4b1005 100644 --- a/src/overlay056/ov56_022561C0.c +++ b/src/overlay056/ov56_022561C0.c @@ -801,7 +801,7 @@ static void ov56_02256EE8(UnkStruct_ov56_02256468 *param0, u32 param1, Sentence v0->unk_00[*v2].unk_14 = *param2; v0->unk_00[*v2].unk_0C = param1; v0->unk_00[*v2].unk_10 = TrainerInfo_Gender(param3); - v0->unk_00[*v2].unk_04 = sub_02014B34(param2, HEAP_ID_89); + v0->unk_00[*v2].unk_04 = Sentence_AsString(param2, HEAP_ID_89); v0->unk_00[*v2].unk_08 = ov56_02256E5C(v1, param1, param0->unk_18, param0->unk_1C, param0->unk_10); (*v2)++; @@ -815,7 +815,7 @@ static int ov56_02256FC8(UnkStruct_ov56_02256468 *param0, Sentence *param1, int { int v0, v1; - if (!sub_02014BBC(param1)) { + if (!Sentence_IsValid(param1)) { return 0; } diff --git a/src/overlay062/ov62_02231690.c b/src/overlay062/ov62_02231690.c index ea82a5f897..dfc7149a8a 100644 --- a/src/overlay062/ov62_02231690.c +++ b/src/overlay062/ov62_02231690.c @@ -516,7 +516,7 @@ static void ov62_02231C78(UnkStruct_ov62_022323B8 *param0, UnkStruct_0208C06C *p v8 = sub_02030C28(v11, &v15, HEAP_ID_102); if (v8 == NULL) { - v8 = sub_02014B34(&v15, HEAP_ID_102); + v8 = Sentence_AsString(&v15, HEAP_ID_102); } Window_FillTilemap(v10, 0x00); diff --git a/src/overlay075/ov75_021D0D80.c b/src/overlay075/ov75_021D0D80.c deleted file mode 100644 index e98ce81896..0000000000 --- a/src/overlay075/ov75_021D0D80.c +++ /dev/null @@ -1,944 +0,0 @@ -#include "overlay075/ov75_021D0D80.h" - -#include -#include - -#include "constants/narc.h" - -#include "struct_defs/struct_020978D8.h" - -#include "bg_window.h" -#include "enums.h" -#include "font.h" -#include "game_options.h" -#include "gx_layers.h" -#include "heap.h" -#include "menu.h" -#include "message.h" -#include "narc.h" -#include "network_icon.h" -#include "overlay_manager.h" -#include "palette.h" -#include "pokemon_icon.h" -#include "render_oam.h" -#include "render_text.h" -#include "render_window.h" -#include "screen_fade.h" -#include "sound_playback.h" -#include "sprite_system.h" -#include "string_gf.h" -#include "sys_task.h" -#include "sys_task_manager.h" -#include "system.h" -#include "text.h" -#include "unk_02014A84.h" -#include "vram_transfer.h" - -enum { - UnkEnum_ov75_021D1598_00, - UnkEnum_ov75_021D1598_01, - UnkEnum_ov75_021D1598_02, - UnkEnum_ov75_021D1598_03, - UnkEnum_ov75_021D1598_04, - UnkEnum_ov75_021D1598_05, - UnkEnum_ov75_021D1598_06, - UnkEnum_ov75_021D1598_07, -}; - -enum { - UnkEnum_ov75_021D0E80_00, - UnkEnum_ov75_021D0E80_01, - UnkEnum_ov75_021D0E80_02, - UnkEnum_ov75_021D0E80_03 -} UnkEnum_ov75_021D0E80; - -typedef struct { - enum HeapID heapID; - int unk_04; - u16 unk_08; - u16 unk_0A; - u8 unk_0C; - u8 unk_0D; - u8 unk_0E; - u8 unk_0F; - u8 unk_10; - u8 unk_11; - u8 unk_12; - u8 unk_13; - u8 unk_14; - u8 unk_15; - u8 unk_16; - u8 unk_17; - BgConfig *unk_18; - UnkStruct_020978D8 *unk_1C; - MessageLoader *unk_20; - String *unk_24[3]; - PaletteData *unk_30; - void *unk_34; - void *unk_38; - NNSG2dScreenData *unk_3C; - NNSG2dScreenData *unk_40; - Window unk_44[6]; - Menu *unk_A4; - SpriteSystem *unk_A8; - SpriteManager *unk_AC; - ManagedSprite *unk_B0[3]; -} UnkStruct_ov75_021D1184; - -typedef int (*UnkFuncPtr_ov75_021D1184)(UnkStruct_ov75_021D1184 *); - -static int ov75_021D1184(UnkStruct_ov75_021D1184 *param0); -static int ov75_021D0E5C(UnkStruct_ov75_021D1184 *param0); -static int ov75_021D0E80(UnkStruct_ov75_021D1184 *param0); -static int ov75_021D108C(UnkStruct_ov75_021D1184 *param0); -static void ov75_021D1358(SysTask *param0, void *param1); -static int ov75_021D13E8(UnkStruct_ov75_021D1184 *param0); -static int ov75_021D1434(UnkStruct_ov75_021D1184 *param0); -static void ov75_021D131C(void *param0); -static void ov75_021D1460(void); -static void ov75_021D1480(UnkStruct_ov75_021D1184 *param0); -static void ov75_021D1564(UnkStruct_ov75_021D1184 *param0); -static void ov75_021D1598(UnkStruct_ov75_021D1184 *param0); -static void ov75_021D1868(UnkStruct_ov75_021D1184 *param0); -static void ov75_021D18A8(UnkStruct_ov75_021D1184 *param0); -static void ov75_021D19A8(UnkStruct_ov75_021D1184 *param0); -static void ov75_021D19C8(UnkStruct_ov75_021D1184 *param0); -static void ov75_021D1ADC(UnkStruct_ov75_021D1184 *param0); -static void ov75_021D1CB8(UnkStruct_ov75_021D1184 *param0); - -int ov75_021D0D80(ApplicationManager *appMan, int *param1) -{ - UnkStruct_020978D8 *v0; - UnkStruct_ov75_021D1184 *v1 = (UnkStruct_ov75_021D1184 *)ApplicationManager_Data(appMan); - - Heap_Create(HEAP_ID_APPLICATION, HEAP_ID_41, 0x20000); - v1 = ApplicationManager_NewData(appMan, sizeof(UnkStruct_ov75_021D1184), HEAP_ID_41); - memset(v1, 0, sizeof(UnkStruct_ov75_021D1184)); - - v1->heapID = HEAP_ID_41; - - v1->unk_1C = (UnkStruct_020978D8 *)ApplicationManager_Args(appMan); - v1->unk_0D = v1->unk_0C = v1->unk_1C->unk_00; - v1->unk_11 = v1->unk_1C->unk_02; - v1->unk_12 = v1->unk_1C->unk_03; - v1->unk_17 = v1->unk_16 = v1->unk_11; - v1->unk_1C->unk_00 = 0xFFFF; - v1->unk_10 = Options_TextFrameDelay(v1->unk_1C->options); - v1->unk_0A = Options_Frame(v1->unk_1C->options); - - RenderControlFlags_SetCanABSpeedUpPrint(TRUE); - return 1; -} - -int ov75_021D0DF8(ApplicationManager *appMan, int *param1) -{ - UnkStruct_ov75_021D1184 *v0 = (UnkStruct_ov75_021D1184 *)ApplicationManager_Data(appMan); - - if (ov75_021D1184(v0)) { - return 1; - } - - return 0; -} - -int ov75_021D0E10(ApplicationManager *appMan, int *param1) -{ - UnkStruct_ov75_021D1184 *v0 = (UnkStruct_ov75_021D1184 *)ApplicationManager_Data(appMan); - int heapID; - - RenderControlFlags_SetCanABSpeedUpPrint(FALSE); - - heapID = v0->heapID; - - ApplicationManager_FreeData(appMan); - Heap_Destroy(heapID); - - return 1; -} - -static BOOL ov75_021D0E34(UnkStruct_ov75_021D1184 *param0) -{ - int i = 0; - - for (i = 0; i < 3; i++) { - if (sub_02014BBC(¶m0->unk_1C->unk_1A[i])) { - return FALSE; - } - } - - return TRUE; -} - -static int ov75_021D0E5C(UnkStruct_ov75_021D1184 *param0) -{ - if (gSystem.pressedKeys & (PAD_BUTTON_A | PAD_BUTTON_B)) { - Sound_PlayEffect(SEQ_SE_DP_PIRORIRO2); - return 1; - } - - return 0; -} - -static int ov75_021D0E80(UnkStruct_ov75_021D1184 *param0) -{ - u8 v0 = 0; - - if (gSystem.pressedKeys & (PAD_BUTTON_A)) { - if (param0->unk_11 == 3) { - if (param0->unk_12 == 0) { - if (ov75_021D0E34(param0)) { - Sound_PlayEffect(SEQ_SE_DP_DECIDE); - param0->unk_0C = UnkEnum_ov75_021D0E80_02; - return 0; - } else { - param0->unk_1C->unk_00 = 3; - Sound_PlayEffect(SEQ_SE_DP_PIRORIRO2); - } - } else { - Sound_PlayEffect(SEQ_SE_DP_DECIDE); - param0->unk_0C = UnkEnum_ov75_021D0E80_03; - return 0; - } - - param0->unk_1C->unk_02 = param0->unk_1C->unk_03 = 0; - } else { - param0->unk_1C->unk_00 = param0->unk_1C->unk_02 = param0->unk_11; - param0->unk_1C->unk_03 = param0->unk_12; - Sound_PlayEffect(SEQ_SE_DP_DECIDE); - } - - return 1; - } else if (gSystem.pressedKeys & (PAD_BUTTON_B)) { - Sound_PlayEffect(SEQ_SE_DP_DECIDE); - param0->unk_0C = UnkEnum_ov75_021D0E80_03; - return 0; - } - - if (gSystem.pressedKeys & PAD_BUTTON_START) { - param0->unk_11 = 3; - param0->unk_12 = 0; - v0 = 1; - } else if (gSystem.pressedKeys & PAD_KEY_DOWN) { - param0->unk_11 = (param0->unk_11 + 1) % 4; - v0 = 1; - } else if (gSystem.pressedKeys & PAD_KEY_UP) { - param0->unk_11 = (param0->unk_11 + 4 - 1) % 4; - v0 = 1; - } else if (gSystem.pressedKeys & (PAD_KEY_RIGHT | PAD_KEY_LEFT)) { - if (param0->unk_11 == 3) { - param0->unk_12 ^= 1; - v0 = 1; - } - } else { - return 0; - } - - if (!v0) { - return 0; - } - - Sound_PlayEffect(SEQ_SE_CONFIRM); - - if (param0->unk_11 == 3) { - param0->unk_16 = param0->unk_11 + param0->unk_12; - } else { - param0->unk_16 = param0->unk_11; - } - - return 0; -} - -static int ov75_021D0FA0(UnkStruct_ov75_021D1184 *param0) -{ - String *v0 = NULL; - - switch (param0->unk_08) { - case 0: - Window_DrawMessageBoxWithScrollCursor(¶m0->unk_44[5], 1, 1 + 9, UnkEnum_ov75_021D1598_06); - Window_FillTilemap(&(param0->unk_44[5]), (15 << 4) | 15); - - v0 = String_Init(19 * 2 * 2, param0->heapID); - - MessageLoader_GetString(param0->unk_20, 2, v0); - Text_AddPrinterWithParamsAndColor(¶m0->unk_44[5], FONT_MESSAGE, v0, 0, 0, TEXT_SPEED_INSTANT, TEXT_COLOR(1, 2, 15), NULL); - String_Free(v0); - break; - case 1: - - if (!(gSystem.pressedKeys & (PAD_BUTTON_A | PAD_BUTTON_B))) { - return 0; - } - - Window_EraseMessageBox(¶m0->unk_44[5], 1); - Window_ClearAndCopyToVRAM(&(param0->unk_44[5])); - - param0->unk_08 = 0; - param0->unk_0C = param0->unk_0D; - - return 0; - } - - param0->unk_08++; - return 0; -} - -static void ov75_021D1040(UnkStruct_ov75_021D1184 *param0) -{ - static const WindowTemplate v0 = { - 0, 25, 13, 6, 4, UnkEnum_ov75_021D1598_03, 555 - }; - - param0->unk_A4 = Menu_MakeYesNoChoice(param0->unk_18, &v0, 1, UnkEnum_ov75_021D1598_05, param0->heapID); -} - -static int ov75_021D1064(UnkStruct_ov75_021D1184 *param0) -{ - switch (Menu_ProcessInputAndHandleExit(param0->unk_A4, param0->heapID)) { - case 0: - return 1; - case 0xfffffffe: - return 0; - } - - return -1; -} - -static int ov75_021D108C(UnkStruct_ov75_021D1184 *param0) -{ - int v0; - String *v1 = NULL; - - switch (param0->unk_08) { - case 0: - param0->unk_13 = 1; - - Window_DrawMessageBoxWithScrollCursor(¶m0->unk_44[5], 1, 1 + 9, UnkEnum_ov75_021D1598_06); - Window_FillTilemap(&(param0->unk_44[5]), (15 << 4) | 15); - - v1 = String_Init(19 * 2 * 2, param0->heapID); - MessageLoader_GetString(param0->unk_20, 3, v1); - param0->unk_0F = Text_AddPrinterWithParamsAndColor(¶m0->unk_44[5], FONT_MESSAGE, v1, 0, 0, param0->unk_10, TEXT_COLOR(1, 2, 15), NULL); - - String_Free(v1); - PaletteData_Blend(param0->unk_30, 0, 34 + param0->unk_17, 1, 0, 0x7FFF); - - param0->unk_17 = param0->unk_16; - param0->unk_15 = 0; - param0->unk_14 = 0; - break; - case 1: - if (Text_IsPrinterActive(param0->unk_0F)) { - return 0; - } - - ov75_021D1040(param0); - break; - case 2: - v0 = ov75_021D1064(param0); - - if (v0 < 0) { - return 0; - } - - Window_EraseMessageBox(¶m0->unk_44[5], 1); - Window_ClearAndCopyToVRAM(&(param0->unk_44[5])); - param0->unk_08 = 0; - - if (v0) { - param0->unk_1C->unk_00 = 0xFFFF; - return 1; - } else { - param0->unk_0C = param0->unk_0D; - param0->unk_13 = 0; - return 0; - } - } - - param0->unk_08++; - return 0; -} - -static int ov75_021D1184(UnkStruct_ov75_021D1184 *param0) -{ - switch (param0->unk_04) { - case 0: - SetVBlankCallback(NULL, NULL); - DisableHBlank(); - GXLayers_DisableEngineALayers(); - GXLayers_DisableEngineBLayers(); - - GX_SetVisiblePlane(0); - GXS_SetVisiblePlane(0); - - SetScreenColorBrightness(DS_SCREEN_MAIN, COLOR_BLACK); - SetScreenColorBrightness(DS_SCREEN_SUB, COLOR_BLACK); - ResetVisibleHardwareWindows(DS_SCREEN_MAIN); - ResetVisibleHardwareWindows(DS_SCREEN_SUB); - break; - case 1: - if (!ov75_021D13E8(param0)) { - return 0; - } - - SetVBlankCallback(ov75_021D131C, param0); - GXLayers_EngineAToggleLayers(GX_PLANEMASK_OBJ, 1); - ResetScreenMasterBrightness(DS_SCREEN_MAIN); - - G2_SetBlendAlpha(GX_BLEND_PLANEMASK_BG2, GX_BLEND_PLANEMASK_BG3, 28, 4); - - PaletteData_StartFade(param0->unk_30, 0x1 | 0x4, 0xFFFF, -1, 16, 0, 0x0); - break; - case 2: - if (param0->unk_AC != NULL) { - SpriteSystem_DrawSprites(param0->unk_AC); - } - - if (PaletteData_GetSelectedBuffersMask(param0->unk_30)) { - return 0; - } - break; - case 3: { - static const UnkFuncPtr_ov75_021D1184 v0[] = { - ov75_021D0E5C, - ov75_021D0E80, - ov75_021D0FA0, - ov75_021D108C, - }; - - if (param0->unk_AC != NULL) { - SpriteSystem_DrawSprites(param0->unk_AC); - } - - if (!v0[param0->unk_0C](param0)) { - return 0; - } - - PaletteData_StartFade(param0->unk_30, 0x1 | 0x4, 0xFFFF, -1, 0, 16, 0x0); - } break; - case 4: - if (PaletteData_GetSelectedBuffersMask(param0->unk_30)) { - if (param0->unk_AC != NULL) { - SpriteSystem_DrawSprites(param0->unk_AC); - } - - return 0; - } - - SetScreenColorBrightness(DS_SCREEN_MAIN, COLOR_BLACK); - SetScreenColorBrightness(DS_SCREEN_SUB, COLOR_BLACK); - SetVBlankCallback(NULL, NULL); - GXLayers_DisableEngineALayers(); - GXLayers_DisableEngineBLayers(); - - GX_SetVisiblePlane(0); - GXS_SetVisiblePlane(0); - break; - case 5: - if (ov75_021D1434(param0)) { - return 1; - } - - return 0; - } - - param0->unk_04++; - return 0; -} - -static void ov75_021D131C(void *param0) -{ - UnkStruct_ov75_021D1184 *v0 = (UnkStruct_ov75_021D1184 *)param0; - - if (v0->unk_30 != NULL) { - PaletteData_CommitFadedBuffers(v0->unk_30); - } - - if (v0->unk_A8 != NULL) { - SpriteSystem_TransferOam(); - } - - NNS_GfdDoVramTransfer(); - Bg_RunScheduledUpdates(v0->unk_18); - - OS_SetIrqCheckFlag(OS_IE_V_BLANK); -} - -static void ov75_021D1358(SysTask *param0, void *param1) -{ - UnkStruct_ov75_021D1184 *v0 = (UnkStruct_ov75_021D1184 *)param1; - - if (v0->unk_30 == NULL) { - SysTask_Done(param0); - return; - } - - if (v0->unk_13) { - return; - } - - if (v0->unk_17 != v0->unk_16) { - PaletteData_Blend(v0->unk_30, 0, 34 + v0->unk_17, 1, 0, 0x7FFF); - v0->unk_17 = v0->unk_16; - v0->unk_15 = 0; - v0->unk_14 = 0; - } - - PaletteData_Blend(v0->unk_30, 0, 34 + v0->unk_16, 1, v0->unk_14, 0x7FFF); - - if (v0->unk_15) { - if (v0->unk_14-- == 1) { - v0->unk_15 ^= 1; - } - } else { - if (v0->unk_14++ == 12) { - v0->unk_15 ^= 1; - } - } -} - -static int ov75_021D13E8(UnkStruct_ov75_021D1184 *param0) -{ - switch (param0->unk_08) { - case 0: - ov75_021D1480(param0); - break; - case 1: - ov75_021D1598(param0); - break; - case 2: - ov75_021D18A8(param0); - ov75_021D19C8(param0); - break; - case 3: - ov75_021D1ADC(param0); - param0->unk_08 = 0; - return 1; - } - - param0->unk_08++; - return 0; -} - -static int ov75_021D1434(UnkStruct_ov75_021D1184 *param0) -{ - ov75_021D1CB8(param0); - - if (param0->unk_24 != NULL) { - MessageLoader_Free(param0->unk_20); - } - - ov75_021D19A8(param0); - ov75_021D1868(param0); - ov75_021D1564(param0); - - return 1; -} - -static void ov75_021D1460(void) -{ - GXBanks v0 = { - GX_VRAM_BG_128_A, - GX_VRAM_BGEXTPLTT_NONE, - GX_VRAM_SUB_BG_128_C, - GX_VRAM_SUB_BGEXTPLTT_NONE, - GX_VRAM_OBJ_64_E, - GX_VRAM_OBJEXTPLTT_NONE, - GX_VRAM_SUB_OBJ_16_I, - GX_VRAM_SUB_OBJEXTPLTT_NONE, - GX_VRAM_TEX_NONE, - GX_VRAM_TEXPLTT_NONE - }; - - GXLayers_SetBanks(&v0); -} - -static void ov75_021D1480(UnkStruct_ov75_021D1184 *param0) -{ - int v0, v1; - - ov75_021D1460(); - - param0->unk_18 = BgConfig_New(param0->heapID); - - { - GraphicsModes v2 = { - GX_DISPMODE_GRAPHICS, - GX_BGMODE_0, - GX_BGMODE_0, - GX_BG0_AS_2D - }; - - SetAllGraphicsModes(&v2); - } - - { - BgTemplate v3[] = { - { - .x = 0, - .y = 0, - .bufferSize = 0x800, - .baseTile = 0, - .screenSize = BG_SCREEN_SIZE_256x256, - .colorMode = GX_BG_COLORMODE_16, - .screenBase = GX_BG_SCRBASE_0xf800, - .charBase = GX_BG_CHARBASE_0x10000, - .bgExtPltt = GX_BG_EXTPLTT_01, - .priority = 0, - .areaOver = 0, - .mosaic = FALSE, - }, - { - .x = 0, - .y = 0, - .bufferSize = 0x800, - .baseTile = 0, - .screenSize = BG_SCREEN_SIZE_256x256, - .colorMode = GX_BG_COLORMODE_16, - .screenBase = GX_BG_SCRBASE_0xf000, - .charBase = GX_BG_CHARBASE_0x00000, - .bgExtPltt = GX_BG_EXTPLTT_01, - .priority = 1, - .areaOver = 0, - .mosaic = FALSE, - }, - { - .x = 0, - .y = 0, - .bufferSize = 0x800, - .baseTile = 0, - .screenSize = BG_SCREEN_SIZE_256x256, - .colorMode = GX_BG_COLORMODE_16, - .screenBase = GX_BG_SCRBASE_0xe800, - .charBase = GX_BG_CHARBASE_0x00000, - .bgExtPltt = GX_BG_EXTPLTT_01, - .priority = 2, - .areaOver = 0, - .mosaic = FALSE, - }, - { - .x = 0, - .y = 0, - .bufferSize = 0x800, - .baseTile = 0, - .screenSize = BG_SCREEN_SIZE_256x256, - .colorMode = GX_BG_COLORMODE_16, - .screenBase = GX_BG_SCRBASE_0xe000, - .charBase = GX_BG_CHARBASE_0x00000, - .bgExtPltt = GX_BG_EXTPLTT_01, - .priority = 3, - .areaOver = 0, - .mosaic = FALSE, - }, - { - .x = 0, - .y = 0, - .bufferSize = 0x800, - .baseTile = 0, - .screenSize = BG_SCREEN_SIZE_256x256, - .colorMode = GX_BG_COLORMODE_16, - .screenBase = GX_BG_SCRBASE_0xf800, - .charBase = GX_BG_CHARBASE_0x00000, - .bgExtPltt = GX_BG_EXTPLTT_01, - .priority = 0, - .areaOver = 0, - .mosaic = FALSE, - }, - }; - - Bg_InitFromTemplate(param0->unk_18, BG_LAYER_MAIN_0, &(v3[0]), 0); - Bg_InitFromTemplate(param0->unk_18, BG_LAYER_MAIN_1, &(v3[1]), 0); - Bg_InitFromTemplate(param0->unk_18, BG_LAYER_MAIN_2, &(v3[2]), 0); - Bg_InitFromTemplate(param0->unk_18, BG_LAYER_MAIN_3, &(v3[3]), 0); - Bg_InitFromTemplate(param0->unk_18, BG_LAYER_SUB_0, &(v3[4]), 0); - } - - Bg_ClearTilemap(param0->unk_18, BG_LAYER_MAIN_0); - Bg_ClearTilemap(param0->unk_18, BG_LAYER_MAIN_1); - Bg_ClearTilemap(param0->unk_18, BG_LAYER_MAIN_2); - Bg_ClearTilemap(param0->unk_18, BG_LAYER_MAIN_3); - Bg_ClearTilemap(param0->unk_18, BG_LAYER_SUB_0); - Bg_ClearTilesRange(BG_LAYER_MAIN_0, 32, 0, param0->heapID); - Bg_ClearTilesRange(BG_LAYER_MAIN_1, 32, 0, param0->heapID); - Bg_ClearTilesRange(BG_LAYER_MAIN_2, 32, 0, param0->heapID); - Bg_ClearTilesRange(BG_LAYER_MAIN_3, 32, 0, param0->heapID); - Bg_ClearTilesRange(4, 32, 0, param0->heapID); -} - -static void ov75_021D1564(UnkStruct_ov75_021D1184 *param0) -{ - Bg_FreeTilemapBuffer(param0->unk_18, BG_LAYER_SUB_0); - Bg_FreeTilemapBuffer(param0->unk_18, BG_LAYER_MAIN_3); - Bg_FreeTilemapBuffer(param0->unk_18, BG_LAYER_MAIN_2); - Bg_FreeTilemapBuffer(param0->unk_18, BG_LAYER_MAIN_1); - Bg_FreeTilemapBuffer(param0->unk_18, BG_LAYER_MAIN_0); - Heap_Free(param0->unk_18); -} - -static void ov75_021D1598(UnkStruct_ov75_021D1184 *param0) -{ - void *v0; - u32 v1; - void *v2; - NNSG2dCharacterData *v3; - NNSG2dPaletteData *v4; - NARC *v5; - int v6 = 12 + param0->unk_1C->mailType; - int v7 = 24 + param0->unk_1C->mailType; - int v8 = 0 + param0->unk_1C->mailType; - v5 = NARC_ctor(NARC_INDEX_GRAPHIC__MAIL_GRA, param0->heapID); - - LoadStandardWindowGraphics(param0->unk_18, BG_LAYER_MAIN_0, 1, UnkEnum_ov75_021D1598_05, 0, param0->heapID); - LoadMessageBoxGraphics(param0->unk_18, BG_LAYER_MAIN_0, 1 + 9, UnkEnum_ov75_021D1598_06, param0->unk_0A, param0->heapID); - - v1 = NARC_GetMemberSize(v5, v6); - v2 = Heap_AllocAtEnd(param0->heapID, v1); - NARC_ReadWholeMember(v5, v6, (void *)v2); - - NNS_G2dGetUnpackedCharacterData(v2, &v3); - Bg_LoadTiles(param0->unk_18, 1, v3->pRawData, v3->szByte, 0); - Bg_LoadTiles(param0->unk_18, 4, v3->pRawData, v3->szByte, 0); - Heap_Free(v2); - - v1 = NARC_GetMemberSize(v5, v8); - v2 = Heap_AllocAtEnd(param0->heapID, v1); - NARC_ReadWholeMember(v5, v8, (void *)v2); - - NNS_G2dGetUnpackedPaletteData(v2, &v4); - Bg_LoadPalette(4, v4->pRawData, v4->szByte, 0); - - param0->unk_30 = PaletteData_New(param0->heapID); - - PaletteData_AllocBuffer(param0->unk_30, 0, 32 * UnkEnum_ov75_021D1598_07, param0->heapID); - PaletteData_AllocBuffer(param0->unk_30, 2, 32 * 3, param0->heapID); - PaletteData_LoadBuffer(param0->unk_30, v4->pRawData, 0, 0, 32 * 3); - - if (param0->unk_0C == 1) { - PaletteData_LoadBuffer(param0->unk_30, &(((u16 *)v4->pRawData)[16 * 3]), 0, 16, 32); - } - - PaletteData_LoadBufferFromFileStart(param0->unk_30, 19, 0, param0->heapID, 2, 32 * 3, 0); - PaletteData_LoadBufferFromFileStart(param0->unk_30, 14, 6, param0->heapID, 0, 32, 16 * UnkEnum_ov75_021D1598_03); - PaletteData_LoadBufferFromFileStart(param0->unk_30, 14, 7, param0->heapID, 0, 32, 16 * UnkEnum_ov75_021D1598_04); - PaletteData_LoadBufferFromFileStart(param0->unk_30, 38, 24, param0->heapID, 0, 32, 16 * UnkEnum_ov75_021D1598_05); - PaletteData_LoadBufferFromFileStart(param0->unk_30, 38, 25 + param0->unk_0A, param0->heapID, 0, 32, 16 * UnkEnum_ov75_021D1598_06); - PaletteData_Blend(param0->unk_30, 0, 0, 16 * UnkEnum_ov75_021D1598_07, 16, 0x0); - PaletteData_Blend(param0->unk_30, 2, 0, 16 * 3, 16, 0x0); - PaletteData_SetAutoTransparent(param0->unk_30, 1); - PaletteData_CommitFadedBuffers(param0->unk_30); - Heap_Free(v2); - - v1 = NARC_GetMemberSize(v5, v7); - param0->unk_34 = Heap_Alloc(param0->heapID, v1); - NARC_ReadWholeMember(v5, v7, (void *)param0->unk_34); - NNS_G2dGetUnpackedScreenData(param0->unk_34, &(param0->unk_3C)); - - v1 = NARC_GetMemberSize(v5, 36); - param0->unk_38 = Heap_Alloc(param0->heapID, v1); - NARC_ReadWholeMember(v5, 36, (void *)param0->unk_38); - NNS_G2dGetUnpackedScreenData(param0->unk_38, &(param0->unk_40)); - - NARC_dtor(v5); - Bg_FillTilemapRect(param0->unk_18, 4, 0x2001, 0, 0, 32, 32, 17); - Bg_CopyToTilemapRect(param0->unk_18, 3, 0, 0, 32, 24, param0->unk_3C->rawData, 0, 0, param0->unk_3C->screenWidth / 8, param0->unk_3C->screenHeight / 8); - Bg_ScheduleTilemapTransfer(param0->unk_18, 3); - Bg_ScheduleTilemapTransfer(param0->unk_18, 4); - - if (param0->unk_0C == 1) { - Bg_CopyToTilemapRect(param0->unk_18, 2, 0, 0, 32, 24, param0->unk_40->rawData, 0, 0, param0->unk_40->screenWidth / 8, param0->unk_40->screenHeight / 8); - Bg_ScheduleTilemapTransfer(param0->unk_18, 2); - - param0->unk_14 = 0; - param0->unk_15 = 0; - - SysTask_Start(ov75_021D1358, param0, 0); - } -} - -static void ov75_021D1868(UnkStruct_ov75_021D1184 *param0) -{ - Heap_Free(param0->unk_38); - Heap_Free(param0->unk_34); - PaletteData_FreeBuffer(param0->unk_30, 2); - PaletteData_FreeBuffer(param0->unk_30, 0); - PaletteData_Free(param0->unk_30); - - param0->unk_30 = NULL; - - G2_SetBlendAlpha(GX_BLEND_PLANEMASK_NONE, GX_BLEND_PLANEMASK_NONE, 31, 0); -} - -static void ov75_021D18A8(UnkStruct_ov75_021D1184 *param0) -{ - int v0 = 0; - - Window_Add(param0->unk_18, ¶m0->unk_44[0], 1, 3, 3, 26, 4, 1, 1023 - 26 * 4); - Window_Add(param0->unk_18, ¶m0->unk_44[1], 1, 3, 3 + 4 + 1, 26, 4, 1, (1023 - 26 * 4) - (26 * 4)); - Window_Add(param0->unk_18, ¶m0->unk_44[2], 1, 3, 3 + 4 + 1 + 4 + 1, 26, 4, 1, ((1023 - 26 * 4) - (26 * 4)) - (26 * 4)); - Window_Add(param0->unk_18, ¶m0->unk_44[3], 1, 21, 20, 8, 2, UnkEnum_ov75_021D1598_01, (((1023 - 26 * 4) - (26 * 4)) - (26 * 4)) - 8 * 2); - Window_Add(param0->unk_18, ¶m0->unk_44[4], 1, 3, 20, 8, 2, UnkEnum_ov75_021D1598_01, ((((1023 - 26 * 4) - (26 * 4)) - (26 * 4)) - 8 * 2) - 8 * 2); - Window_Add(param0->unk_18, ¶m0->unk_44[5], 0, 2, 19, 27, 4, UnkEnum_ov75_021D1598_04, (((((1023 - 26 * 4) - (26 * 4)) - (26 * 4)) - 8 * 2) - 8 * 2) - 8 * 2); - - for (v0 = 0; v0 < 6; v0++) { - Window_FillTilemap(&(param0->unk_44[v0]), 0); - - if (v0 < 5) { - Window_CopyToVRAM(¶m0->unk_44[v0]); - } - } -} - -static void ov75_021D19A8(UnkStruct_ov75_021D1184 *param0) -{ - int v0 = 0; - - for (v0 = 0; v0 < 6; v0++) { - Window_ClearAndCopyToVRAM(¶m0->unk_44[v0]); - Window_Remove(¶m0->unk_44[v0]); - } -} - -static void ov75_021D19C8(UnkStruct_ov75_021D1184 *param0) -{ - int v0 = 0; - String *v1; - - for (v0 = 0; v0 < 3; v0++) { - if (!sub_02014BBC(¶m0->unk_1C->unk_1A[v0])) { - continue; - } - - v1 = sub_02014B34(¶m0->unk_1C->unk_1A[v0], param0->heapID); - - Text_AddPrinterWithParamsAndColor(¶m0->unk_44[0 + v0], FONT_MESSAGE, v1, 0, 0, TEXT_SPEED_INSTANT, TEXT_COLOR(1, 2, 0), NULL); - String_Free(v1); - Window_CopyToVRAM(¶m0->unk_44[0 + v0]); - } - - if (param0->unk_0C == 1) { - String *v2; - int v3; - - param0->unk_20 = MessageLoader_Init(MSG_LOADER_LOAD_ON_DEMAND, NARC_INDEX_MSGDATA__PL_MSG, TEXT_BANK_UNK_0409, param0->heapID); - - v2 = String_Init(8 * 2, param0->heapID); - - for (v0 = 0; v0 < 2; v0++) { - String_Clear(v2); - MessageLoader_GetString(param0->unk_20, 0 + v0, v2); - - v3 = (8 * 8) - Font_CalcStringWidth(FONT_MESSAGE, v2, 0); - v3 /= 2; - - Text_AddPrinterWithParamsAndColor(¶m0->unk_44[3 + v0], FONT_MESSAGE, v2, v3, 2, TEXT_SPEED_INSTANT, TEXT_COLOR(1, 2, 0), NULL); - Window_CopyToVRAM(¶m0->unk_44[3 + v0]); - } - - String_Free(v2); - } else { - Text_AddPrinterWithParamsAndColor(¶m0->unk_44[3], FONT_MESSAGE, param0->unk_1C->unk_10, 0, 2, TEXT_SPEED_INSTANT, TEXT_COLOR(1, 2, 0), NULL); - Window_CopyToVRAM(¶m0->unk_44[3]); - } -} - -static void ov75_021D1ADC(UnkStruct_ov75_021D1184 *param0) -{ - int v0 = 0, v1 = 0; - SpriteTemplate v2; - - NetworkIcon_InitIfConnected(); - - if (param0->unk_0C == 1) { - return; - } - - VramTransfer_New(32, param0->heapID); - - param0->unk_A8 = SpriteSystem_Alloc(param0->heapID); - param0->unk_AC = SpriteManager_New(param0->unk_A8); - - { - RenderOamTemplate v3 = { - 0, - 7, - 1, - 1, - 0, - 1, - 1, - 1, - }; - CharTransferTemplateWithModes v4 = { - 3, - 1024, - 0, - GX_OBJVRAMMODE_CHAR_1D_32K, - GX_OBJVRAMMODE_CHAR_1D_32K, - }; - const SpriteResourceCapacities v5 = { - 3, - 1, - 1, - 1, - 0, - 0, - }; - - SpriteSystem_Init(param0->unk_A8, &v3, &v4, 32); - SpriteSystem_InitSprites(param0->unk_A8, param0->unk_AC, 3); - SpriteSystem_InitManagerWithCapacities(param0->unk_A8, param0->unk_AC, &v5); - RenderOam_ClearMain(param0->heapID); - } - - SpriteSystem_LoadPlttResObj(param0->unk_A8, param0->unk_AC, NARC_INDEX_POKETOOL__ICONGRA__PL_POKE_ICON, PokeIconPalettesFileIndex(), FALSE, 3, NNS_G2D_VRAM_TYPE_2DMAIN, 0); - SpriteSystem_LoadCellResObj(param0->unk_A8, param0->unk_AC, NARC_INDEX_POKETOOL__ICONGRA__PL_POKE_ICON, PokeIconCellsFileIndex(), FALSE, 0); - SpriteSystem_LoadAnimResObj(param0->unk_A8, param0->unk_AC, NARC_INDEX_POKETOOL__ICONGRA__PL_POKE_ICON, PokeIconAnimationFileIndex(), FALSE, 0); - - for (v0 = 0; v0 < 3; v0++) { - if (param0->unk_1C->unk_14[v0].val2 == 0xFFFF) { - break; - } - - SpriteSystem_LoadCharResObjWithHardwareMappingType(param0->unk_A8, param0->unk_AC, NARC_INDEX_POKETOOL__ICONGRA__PL_POKE_ICON, param0->unk_1C->unk_14[v0].val1_0, FALSE, NNS_G2D_VRAM_TYPE_2DMAIN, v0); - MI_CpuClear8(&v2, sizeof(SpriteTemplate)); - - v2.x = (16 * 8) - (40 * v0); - v2.y = 160; - v2.z = 0; - - v2.animIdx = 0; - v2.bgPriority = 2; - v2.plttIdx = param0->unk_1C->unk_14[v0].val1_12; - v2.vramTransfer = FALSE; - v2.vramType = NNS_G2D_VRAM_TYPE_2DMAIN; - - v2.resources[0] = v0; - v2.resources[1] = 0; - v2.resources[2] = 0; - v2.resources[3] = 0; - v2.resources[4] = SPRITE_RESOURCE_NONE; - v2.resources[5] = SPRITE_RESOURCE_NONE; - - param0->unk_B0[v0] = SpriteSystem_NewSprite(param0->unk_A8, param0->unk_AC, &v2); - - if (param0->unk_1C->unk_14[v0].val1_0 == 7) { - ManagedSprite_SetDrawFlag(param0->unk_B0[v0], 0); - } - } -} - -static void ov75_021D1CB8(UnkStruct_ov75_021D1184 *param0) -{ - int v0 = 0; - - if (param0->unk_0C == 0) { - for (v0 = 0; v0 < 3; v0++) { - if (param0->unk_B0[v0] != NULL) { - Sprite_DeleteAndFreeResources(param0->unk_B0[v0]); - } - } - - SpriteSystem_FreeResourcesAndManager(param0->unk_A8, param0->unk_AC); - SpriteSystem_Free(param0->unk_A8); - VramTransfer_Free(); - } -} diff --git a/src/overlay090/ov90_021D0D80.c b/src/overlay090/ov90_021D0D80.c index 5326fb9ecd..dad9141451 100644 --- a/src/overlay090/ov90_021D0D80.c +++ b/src/overlay090/ov90_021D0D80.c @@ -824,7 +824,7 @@ static void ov90_021D1A48(UnkStruct_ov90_021D0ECC *param0) String *v0; UnkStruct_ov90_021D17F8 *v1 = &(param0->unk_BC[param0->unk_0B * 3 + param0->unk_0C]); - v0 = sub_02014B34(&v1->unk_08, param0->heapID); + v0 = Sentence_AsString(&v1->unk_08, param0->heapID); Window_FillTilemap(¶m0->unk_6C[2], (0 << 4) | 0); Text_AddPrinterWithParamsAndColor(¶m0->unk_6C[2], FONT_SYSTEM, v0, 0, 4, TEXT_SPEED_INSTANT, TEXT_COLOR(1, 2, 0), NULL); diff --git a/src/overlay104/ov104_02231F74.c b/src/overlay104/ov104_02231F74.c index a516b2f8f4..6267488b65 100644 --- a/src/overlay104/ov104_02231F74.c +++ b/src/overlay104/ov104_02231F74.c @@ -169,12 +169,12 @@ static void GetStringFromSentence(String *msgBuf, u16 sentenceType, u16 sentence Sentence sentence; String *string; - sub_02014A84(&sentence); + Sentence_Init(&sentence); sub_02014CE0(&sentence, sentenceType, sentenceID); Sentence_SetWord(&sentence, 0, word1); Sentence_SetWord(&sentence, 1, word2); - string = sub_02014B34(&sentence, HEAP_ID_FIELD3); + string = Sentence_AsString(&sentence, HEAP_ID_FIELD3); String_Copy(msgBuf, string); String_Free(string); } diff --git a/src/pokemon.c b/src/pokemon.c index 5ca8fad1e2..189ae8d1ec 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -21,7 +21,6 @@ #include "generated/species_data_params.h" #include "struct_defs/chatot_cry.h" -#include "struct_defs/mail.h" #include "struct_defs/seal_case.h" #include "struct_defs/species_sprite_data.h" #include "struct_defs/sprite_animation_frame.h" diff --git a/src/savedata/save_table.c b/src/savedata/save_table.c index 3631b65614..e7d957d11d 100644 --- a/src/savedata/save_table.c +++ b/src/savedata/save_table.c @@ -80,7 +80,7 @@ const SaveTableEntry gSaveTable[] = { { SAVE_TABLE_ENTRY_MYSTERY_GIFT, SAVE_BLOCK_ID_NORMAL, (SaveEntrySizeFunc)MysteryGift_SaveSize, (SaveEntryInitFunc)MysteryGift_Init }, { SAVE_TABLE_ENTRY_PAL_PARK_TRANSFER, SAVE_BLOCK_ID_NORMAL, (SaveEntrySizeFunc)MigratedPokemon_SaveSize, (SaveEntryInitFunc)PalParkTransfer_Init }, { SAVE_TABLE_ENTRY_LINK_CONTEST_RECORDS, SAVE_BLOCK_ID_NORMAL, (SaveEntrySizeFunc)LinkContestRecords_SaveSize, (SaveEntryInitFunc)LinkContestRecords_Init }, - { SAVE_TABLE_ENTRY_SENTENCE, SAVE_BLOCK_ID_NORMAL, (SaveEntrySizeFunc)Sentence_SaveSize, (SaveEntryInitFunc)Sentence_Init }, + { SAVE_TABLE_ENTRY_SENTENCE, SAVE_BLOCK_ID_NORMAL, (SaveEntrySizeFunc)Sentence_SaveSize, (SaveEntryInitFunc)SentenceSaveData_Init }, { SAVE_TABLE_ENTRY_EMAIL, SAVE_BLOCK_ID_NORMAL, (SaveEntrySizeFunc)Email_SaveSize, (SaveEntryInitFunc)Email_Init }, { SAVE_TABLE_ENTRY_WIFI_QUESTIONS, SAVE_BLOCK_ID_NORMAL, (SaveEntrySizeFunc)WiFiQuestion_SaveSize, (SaveEntryInitFunc)WiFiQuestion_Init }, { SAVE_TABLE_ENTRY_PC_BOXES, SAVE_BLOCK_ID_BOXES, (SaveEntrySizeFunc)PCBoxes_SaveSize, (SaveEntryInitFunc)PCBoxes_Init }, diff --git a/src/savedata_misc.c b/src/savedata_misc.c index 61d9adacf3..36e0e4d307 100644 --- a/src/savedata_misc.c +++ b/src/savedata_misc.c @@ -27,7 +27,7 @@ void MiscSaveBlock_Init(MiscSaveBlock *miscSave) MI_CpuFill16(miscSave->rivalName, CHAR_EOS, TRAINER_NAME_LEN + 1); MI_CpuFill16(miscSave->tabletName, CHAR_EOS, TABLET_NAME_LEN + 1); - sub_02014A9C(&miscSave->introMsg, 4); + Sentence_InitWithType(&miscSave->introMsg, 4); miscSave->introMsg.id = 0; miscSave->introMsg.words[0] = sub_02014DFC(441, 99); diff --git a/src/scrcmd.c b/src/scrcmd.c index dd8e2b105a..3e9f76b826 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -35,7 +35,6 @@ #include "struct_defs/daycare.h" #include "struct_defs/dress_up_photo.h" #include "struct_defs/image_clips.h" -#include "struct_defs/mail.h" #include "struct_defs/seal_case.h" #include "struct_defs/special_encounter.h" #include "struct_defs/struct_02029C88.h" @@ -546,7 +545,7 @@ static BOOL ScrCmd_HatchEgg(ScriptContext *ctx); static BOOL ScrCmd_ShowObject(ScriptContext *ctx); static BOOL ScrCmd_HideObject(ScriptContext *ctx); static BOOL ScrCmd_1B3(ScriptContext *ctx); -static BOOL ScrCmd_1B4(ScriptContext *ctx); +static BOOL ScrCmd_CountMailInMailbox(ScriptContext *ctx); static BOOL ScrCmd_StartRankingsMachine(ScriptContext *ctx); static BOOL ScrCmd_GetTimeOfDay(ScriptContext *ctx); static BOOL ScrCmd_GetRandom(ScriptContext *ctx); @@ -4916,13 +4915,13 @@ static BOOL ScrCmd_1B3(ScriptContext *ctx) return TRUE; } -static BOOL ScrCmd_1B4(ScriptContext *ctx) +static BOOL ScrCmd_CountMailInMailbox(ScriptContext *ctx) { FieldSystem *fieldSystem = ctx->fieldSystem; u16 *destVar = ScriptContext_GetVarPointer(ctx); Mailbox *mailbox = SaveData_GetMailbox(fieldSystem->saveData); - *destVar = (u16)sub_02028494(mailbox, 0); + *destVar = Mailbox_CountMail(mailbox, MAIL_CONTEXT_MAILBOX); return FALSE; } diff --git a/src/start_menu.c b/src/start_menu.c index caea334192..cc0f238530 100644 --- a/src/start_menu.c +++ b/src/start_menu.c @@ -12,11 +12,10 @@ #include "generated/species.h" #include "generated/text_banks.h" -#include "struct_decls/struct_0209747C_decl.h" #include "struct_defs/sentence.h" -#include "struct_defs/struct_02097728.h" #include "applications/bag/application.h" +#include "applications/mail.h" #include "applications/party_menu/defs.h" #include "applications/party_menu/main.h" #include "applications/poffin_case/main.h" @@ -87,7 +86,6 @@ #include "unk_0206B9D8.h" #include "unk_020972FC.h" #include "unk_0209747C.h" -#include "unk_02097624.h" #include "vars_flags.h" #include "res/graphics/start_menu/start_menu.naix" @@ -106,11 +104,11 @@ enum StartMenuOption { START_MENU_OPTION_RETIRE, }; -typedef struct { +typedef struct MenuMailData { u16 itemID; - u8 slot; - u8 unk_03; -} UnkStruct_0203C540; + u8 partySlot; + u8 usageType; +} MenuMailData; typedef struct MenuEvolutionData { u8 slot; @@ -181,7 +179,7 @@ static BOOL StartMenu_ExitBerryTag(FieldTask *fieldTask); static void StartMenu_EvolveInit(FieldTask *fieldTask); static void StartMenu_Evolve(FieldTask *fieldTask); static BOOL StartMenu_SelectRetire(FieldTask *fieldTask); -static void sub_0203C668(FieldSystem *fieldSystem, StartMenu *menu, u8 mode); +static void StartMenu_ProcessGivenMail(FieldSystem *fieldSystem, StartMenu *menu, u8 mode); typedef struct StartMenuAction { u32 bankEntry; @@ -1035,24 +1033,22 @@ BOOL StartMenu_ExitPartyMenu(FieldTask *fieldTask) menu->taskData = summary; StartMenu_SetCallback(menu, StartMenu_ExitSummary); break; - case PARTY_MENU_EXIT_CODE_MAIL: - UnkStruct_02097728 *v8 = sub_0203D920(fieldSystem, 2, partyMenu->selectedMonSlot, Item_MailNumber(partyMenu->usedItemID), HEAP_ID_FIELD2); - menu->taskData = v8; + case PARTY_MENU_EXIT_CODE_WRITE_MAIL: + menu->taskData = FieldSystem_LaunchMailApp_Write(fieldSystem, MAIL_CONTEXT_WRITE, partyMenu->selectedMonSlot, Item_GetMailType(partyMenu->usedItemID), HEAP_ID_FIELD2); if (partyMenu->mode == PARTY_MENU_MODE_GIVE_ITEM_DONE) { - menu->additionalTaskContext = sub_0203C540(partyMenu->usedItemID, 0, partyMenu->selectedMonSlot); + menu->additionalTaskContext = StartMenu_BuildMailData(partyMenu->usedItemID, MAIL_GIVE_FROM_PARTY_MENU, partyMenu->selectedMonSlot); } else { - menu->additionalTaskContext = sub_0203C540(partyMenu->usedItemID, 1, partyMenu->selectedMonSlot); + menu->additionalTaskContext = StartMenu_BuildMailData(partyMenu->usedItemID, MAIL_GIVE_FROM_BAG, partyMenu->selectedMonSlot); } StartMenu_SetCallback(menu, StartMenu_ExitMail); break; case PARTY_MENU_EXIT_CODE_READ_MAIL: Pokemon *mon = Party_GetPokemonBySlotIndex(SaveData_GetParty(fieldSystem->saveData), partyMenu->selectedMonSlot); - UnkStruct_02097728 *v9 = sub_0203D984(fieldSystem, mon, HEAP_ID_FIELD2); - menu->taskData = v9; - menu->additionalTaskContext = sub_0203C540(partyMenu->usedItemID, 2, partyMenu->selectedMonSlot); + menu->taskData = FieldSystem_LaunchMailApp_ReadHeld(fieldSystem, mon, HEAP_ID_FIELD2); + menu->additionalTaskContext = StartMenu_BuildMailData(partyMenu->usedItemID, MAIL_READ_FROM_PARTY_MENU, partyMenu->selectedMonSlot); StartMenu_SetCallback(menu, StartMenu_ExitMail); break; @@ -1222,9 +1218,8 @@ static BOOL StartMenu_ExitBag(FieldTask *fieldTask) Heap_Free(menu->additionalTaskContext); if (Item_IsMail(item) == TRUE && Pokemon_GetValue(mon, MON_DATA_HELD_ITEM, NULL) == ITEM_NONE) { - UnkStruct_02097728 *v11 = sub_0203D920(fieldSystem, 2, slot, Item_MailNumber(item), HEAP_ID_FIELD2); - menu->taskData = v11; - menu->additionalTaskContext = sub_0203C540(item, 0, slot); + menu->taskData = FieldSystem_LaunchMailApp_Write(fieldSystem, MAIL_CONTEXT_WRITE, slot, Item_GetMailType(item), HEAP_ID_FIELD2); + menu->additionalTaskContext = StartMenu_BuildMailData(item, MAIL_GIVE_FROM_PARTY_MENU, slot); StartMenu_SetCallback(menu, StartMenu_ExitMail); } else { PartyMenu *partyMenu = Heap_Alloc(HEAP_ID_FIELD2, sizeof(PartyMenu)); @@ -1411,7 +1406,7 @@ static BOOL StartMenu_Chat(FieldTask *fieldTask) menu->taskData = sub_0209747C(2, 0, fieldSystem->saveData, HEAP_ID_FIELD2); Sentence sentence; - sub_02014A9C(&sentence, 4); + Sentence_InitWithType(&sentence, 4); sub_02097500(menu->taskData, &sentence); sub_0203D874(fieldSystem, (UnkStruct_0209747C *)menu->taskData); @@ -1617,48 +1612,48 @@ BOOL StartMenu_ExitJournal(FieldTask *fieldTask) return FALSE; } -void *sub_0203C540(u16 itemID, u8 param1, u8 slot) +void *StartMenu_BuildMailData(u16 itemID, u8 usageType, u8 partySlot) { - UnkStruct_0203C540 *v0 = Heap_Alloc(HEAP_ID_FIELD2, sizeof(UnkStruct_0203C540)); + MenuMailData *data = Heap_Alloc(HEAP_ID_FIELD2, sizeof(MenuMailData)); - v0->itemID = itemID; - v0->slot = slot; - v0->unk_03 = param1; + data->itemID = itemID; + data->partySlot = partySlot; + data->usageType = usageType; - return (void *)v0; + return (void *)data; } BOOL StartMenu_ExitMail(FieldTask *fieldTask) { FieldSystem *fieldSystem = FieldTask_GetFieldSystem(fieldTask); StartMenu *menu = FieldTask_GetEnv(fieldTask); - UnkStruct_0203C540 *v2 = menu->additionalTaskContext; + MenuMailData *data = menu->additionalTaskContext; - switch (v2->unk_03) { - case 3: - sub_02097770(menu->taskData); + switch (data->usageType) { + case MAIL_READ_FROM_BAG: + MailAppArgs_Free(menu->taskData); menu->taskData = FieldSystem_OpenBag(fieldSystem, &menu->itemUseCtx); StartMenu_SetCallback(menu, StartMenu_ExitBag); break; - case 2: - sub_02097770(menu->taskData); - menu->taskData = FieldSystem_OpenPartyMenu(fieldSystem, &menu->fieldMoveContext, v2->slot); + case MAIL_READ_FROM_PARTY_MENU: + MailAppArgs_Free(menu->taskData); + menu->taskData = FieldSystem_OpenPartyMenu(fieldSystem, &menu->fieldMoveContext, data->partySlot); StartMenu_SetCallback(menu, StartMenu_ExitPartyMenu); break; - case 0: - if (sub_02097728(menu->taskData) == 1) { - sub_0203C668(fieldSystem, menu, PARTY_MENU_MODE_GIVE_MAIL_DONE); + case MAIL_GIVE_FROM_PARTY_MENU: + if (MailApp_WasMailWritten(menu->taskData) == TRUE) { + StartMenu_ProcessGivenMail(fieldSystem, menu, PARTY_MENU_MODE_GIVE_MAIL_DONE); } else { - sub_02097770(menu->taskData); - menu->taskData = FieldSystem_OpenPartyMenu(fieldSystem, &menu->fieldMoveContext, v2->slot); + MailAppArgs_Free(menu->taskData); + menu->taskData = FieldSystem_OpenPartyMenu(fieldSystem, &menu->fieldMoveContext, data->partySlot); StartMenu_SetCallback(menu, StartMenu_ExitPartyMenu); } break; - case 1: - if (sub_02097728(menu->taskData) == 1) { - sub_0203C668(fieldSystem, menu, PARTY_MENU_MODE_GIVE_MAIL); + case MAIL_GIVE_FROM_BAG: + if (MailApp_WasMailWritten(menu->taskData) == TRUE) { + StartMenu_ProcessGivenMail(fieldSystem, menu, PARTY_MENU_MODE_GIVE_MAIL); } else { - sub_02097770(menu->taskData); + MailAppArgs_Free(menu->taskData); menu->taskData = FieldSystem_OpenBag(fieldSystem, &menu->itemUseCtx); StartMenu_SetCallback(menu, StartMenu_ExitBag); } @@ -1666,12 +1661,12 @@ BOOL StartMenu_ExitMail(FieldTask *fieldTask) } Heap_Free(menu->additionalTaskContext); - return 0; + return FALSE; } -static void sub_0203C668(FieldSystem *fieldSystem, StartMenu *menu, u8 mode) // TODO: +static void StartMenu_ProcessGivenMail(FieldSystem *fieldSystem, StartMenu *menu, u8 mode) { - UnkStruct_0203C540 *v0 = menu->additionalTaskContext; + MenuMailData *data = menu->additionalTaskContext; PartyMenu *partyMenu = Heap_Alloc(HEAP_ID_FIELD2, sizeof(PartyMenu)); memset(partyMenu, 0, sizeof(PartyMenu)); @@ -1681,13 +1676,13 @@ static void sub_0203C668(FieldSystem *fieldSystem, StartMenu *menu, u8 mode) // partyMenu->options = SaveData_GetOptions(fieldSystem->saveData); partyMenu->fieldMoveContext = &menu->fieldMoveContext; partyMenu->type = PARTY_MENU_TYPE_BASIC; - partyMenu->usedItemID = v0->itemID; - partyMenu->selectedMonSlot = v0->slot; + partyMenu->usedItemID = data->itemID; + partyMenu->selectedMonSlot = data->partySlot; partyMenu->mode = mode; partyMenu->fieldSystem = fieldSystem; - sub_02097750(menu->taskData, Party_GetPokemonBySlotIndex(partyMenu->party, v0->slot)); - sub_02097770(menu->taskData); + MailApp_AddWrittenMailToMon(menu->taskData, Party_GetPokemonBySlotIndex(partyMenu->party, data->partySlot)); + MailAppArgs_Free(menu->taskData); FieldSystem_StartChildProcess(fieldSystem, &gPokemonPartyAppTemplate, partyMenu); menu->taskData = partyMenu; diff --git a/src/unk_02014A84.c b/src/unk_02014A84.c index 482a2e1f75..ca5acc9c07 100644 --- a/src/unk_02014A84.c +++ b/src/unk_02014A84.c @@ -22,32 +22,28 @@ static const u16 Unk_020E5498[] = { 0x1C1 }; -void sub_02014A84(Sentence *sentence) +void Sentence_Init(Sentence *sentence) { - int v0; - sentence->type = 0xffff; - for (v0 = 0; v0 < 2; v0++) { - sentence->words[v0] = 0xffff; + for (int i = 0; i < 2; i++) { + sentence->words[i] = 0xffff; } } -void sub_02014A9C(Sentence *sentence, u32 param1) +void Sentence_InitWithType(Sentence *sentence, u32 type) { - int v0; - - sentence->type = param1; + sentence->type = type; sentence->id = 0; - for (v0 = 0; v0 < 2; v0++) { - sentence->words[v0] = 0xffff; + for (int i = 0; i < 2; i++) { + sentence->words[i] = 0xffff; } } void sub_02014AB4(Sentence *sentence) { - sub_02014A9C(sentence, 4); + Sentence_InitWithType(sentence, 4); sentence->id = 5; } @@ -70,7 +66,7 @@ void sub_02014AC4(Sentence *sentence, int param1) GF_ASSERT(param1 < NELEMS(v0)); if (param1 < NELEMS(v0)) { - sub_02014A9C(sentence, v0[param1].unk_00); + Sentence_InitWithType(sentence, v0[param1].unk_00); sentence->id = v0[param1].unk_01; if (v0[param1].unk_02 != -1) { @@ -85,30 +81,25 @@ void sub_02014AC4(Sentence *sentence, int param1) } } -String *sub_02014B34(const Sentence *sentence, enum HeapID heapID) +String *Sentence_AsString(const Sentence *sentence, enum HeapID heapID) { - String *v0; - StringTemplate *v1; - MessageLoader *v2; - int v3; + StringTemplate *template = StringTemplate_Default(heapID); - v1 = StringTemplate_Default(heapID); - - for (v3 = 0; v3 < 2; v3++) { - if (sentence->words[v3] != 0xffff) { - StringTemplate_SetCustomMessageWord(v1, v3, sentence->words[v3]); + for (int i = 0; i < 2; i++) { + if (sentence->words[i] != 0xffff) { + StringTemplate_SetCustomMessageWord(template, i, sentence->words[i]); } else { break; } } - v2 = MessageLoader_Init(MSG_LOADER_LOAD_ON_DEMAND, NARC_INDEX_MSGDATA__PL_MSG, Unk_020E5498[sentence->type], heapID); - v0 = MessageUtil_ExpandedString(v1, v2, sentence->id, heapID); + MessageLoader *loader = MessageLoader_Init(MSG_LOADER_LOAD_ON_DEMAND, NARC_INDEX_MSGDATA__PL_MSG, Unk_020E5498[sentence->type], heapID); + String *string = MessageUtil_ExpandedString(template, loader, sentence->id, heapID); - MessageLoader_Free(v2); - StringTemplate_Free(v1); + MessageLoader_Free(loader); + StringTemplate_Free(template); - return v0; + return string; } String *sub_02014BA0(const Sentence *sentence, u32 param1) @@ -116,7 +107,7 @@ String *sub_02014BA0(const Sentence *sentence, u32 param1) return MessageBank_GetNewStringFromNARC(26, Unk_020E5498[sentence->type], sentence->id, param1); } -BOOL sub_02014BBC(const Sentence *sentence) +BOOL Sentence_IsValid(const Sentence *sentence) { return sentence->type != 0xffff; } @@ -197,9 +188,9 @@ BOOL sub_02014C88(const Sentence *param0, const Sentence *param1) return 1; } -void sub_02014CC0(Sentence *param0, const Sentence *param1) +void Sentence_Set(Sentence *dest, const Sentence *src) { - *param0 = *param1; + *dest = *src; } u32 sub_02014CD4(u32 param0) diff --git a/src/unk_02014D38.c b/src/unk_02014D38.c index 064c709162..4f08142da8 100644 --- a/src/unk_02014D38.c +++ b/src/unk_02014D38.c @@ -231,7 +231,7 @@ u32 Sentence_SaveSize(void) return sizeof(UnkStruct_02014EC4); } -void Sentence_Init(void *param0) +void SentenceSaveData_Init(void *param0) { static const struct { u8 language; diff --git a/src/unk_020298BC.c b/src/unk_020298BC.c index 65ae808a11..d5aee56f3f 100644 --- a/src/unk_020298BC.c +++ b/src/unk_020298BC.c @@ -542,7 +542,7 @@ void DressUpPhoto_SetTitle(DressUpPhoto *photo, u16 word) { GF_ASSERT(DressUpPhoto_IsValid(photo)); - sub_02014A84(&photo->title); + Sentence_Init(&photo->title); Sentence_SetWord(&photo->title, 0, word); } diff --git a/src/unk_0202D05C.c b/src/unk_0202D05C.c index 2fd0368795..9dd3ede7df 100644 --- a/src/unk_0202D05C.c +++ b/src/unk_0202D05C.c @@ -374,7 +374,7 @@ u32 sub_0202D474(UnkStruct_0202D750 *param0) void sub_0202D478(SaveData *saveData, int param1, Sentence *param2) { BattleFrontier *frontier = SaveData_SaveTable(saveData, SAVE_TABLE_ENTRY_FRONTIER); - sub_02014CC0(&(frontier->unk_950.unk_168.unk_00[param1]), param2); + Sentence_Set(&(frontier->unk_950.unk_168.unk_00[param1]), param2); } Sentence *sub_0202D498(SaveData *saveData, int param1) diff --git a/src/unk_02030A80.c b/src/unk_02030A80.c index 3287df353d..fdd3c537ad 100644 --- a/src/unk_02030A80.c +++ b/src/unk_02030A80.c @@ -163,7 +163,7 @@ String *sub_02030C28(const UnkStruct_02030A80 *param0, Sentence *param1, enum He } if (v0 > 0) { - sub_02014A9C(param1, 4); + Sentence_InitWithType(param1, 4); param1->id = 0; param1->words[0] = sub_02014DFC(441, 99); param1->words[1] = 0xffff; diff --git a/src/unk_02033200.c b/src/unk_02033200.c index 703d284f4a..8cc37cc4de 100644 --- a/src/unk_02033200.c +++ b/src/unk_02033200.c @@ -90,7 +90,7 @@ void CommServerClient_Init(TrainerInfo *trainerInfo, BOOL param1) sCommServerClient->unk_1504 = 0x333; sCommServerClient->personalTrainerInfo = trainerInfo; - sub_02014A84((Sentence *)&sCommServerClient->unk_14EC); + Sentence_Init((Sentence *)&sCommServerClient->unk_14EC); sub_020334DC(param1); } diff --git a/src/unk_0203D1B8.c b/src/unk_0203D1B8.c index dec173f680..db6277799e 100644 --- a/src/unk_0203D1B8.c +++ b/src/unk_0203D1B8.c @@ -9,7 +9,6 @@ #include "generated/pokemon_contest_types.h" #include "generated/trainer_score_events.h" -#include "struct_decls/struct_0209747C_decl.h" #include "struct_defs/choose_starter_data.h" #include "struct_defs/clear_game_player_info.h" #include "struct_defs/dress_up_photo.h" @@ -24,12 +23,12 @@ #include "struct_defs/struct_0203E608.h" #include "struct_defs/struct_0203E6C0.h" #include "struct_defs/struct_0206BC70.h" -#include "struct_defs/struct_02097728.h" #include "applications/bag/application.h" #include "applications/diploma.h" #include "applications/frontier/records/main.h" #include "applications/journal_display/journal_controller.h" +#include "applications/mail.h" #include "applications/move_reminder.h" #include "applications/naming_screen.h" #include "applications/options_menu.h" @@ -126,7 +125,6 @@ #include "unk_020559DC.h" #include "unk_0205B33C.h" #include "unk_0209747C.h" -#include "unk_02097624.h" #include "vars_flags.h" #include "wifi_history_save_data.h" @@ -751,42 +749,42 @@ void *FieldSystem_OpenOptionsMenu(FieldSystem *fieldSystem) return optionsMenu; } -extern const ApplicationManagerTemplate Unk_020F64B0; +extern const ApplicationManagerTemplate gMailAppArgsTemplate; -static void sub_0203D910(FieldSystem *fieldSystem, UnkStruct_02097728 *param1) +static void LaunchMailApp(FieldSystem *fieldSystem, MailAppArgs *mailAppArgs) { - FieldSystem_StartChildProcess(fieldSystem, &Unk_020F64B0, param1); + FieldSystem_StartChildProcess(fieldSystem, &gMailAppArgsTemplate, mailAppArgs); } -UnkStruct_02097728 *sub_0203D920(FieldSystem *fieldSystem, int param1, u8 param2, u8 mailType, int unusedHeapID) +MailAppArgs *FieldSystem_LaunchMailApp_Write(FieldSystem *fieldSystem, enum MailContext context, u8 partySlot, u8 mailType, int unusedHeapID) { - UnkStruct_02097728 *v0 = sub_02097624(FieldSystem_GetSaveData(fieldSystem), param1, param2, mailType, HEAP_ID_FIELD2); - sub_0203D910(fieldSystem, v0); + MailAppArgs *mailAppArgs = MailAppArgs_New_Write(FieldSystem_GetSaveData(fieldSystem), context, partySlot, mailType, HEAP_ID_FIELD2); + LaunchMailApp(fieldSystem, mailAppArgs); - return v0; + return mailAppArgs; } -UnkStruct_02097728 *sub_0203D94C(FieldSystem *fieldSystem, int param1, u8 param2, enum HeapID heapID) +MailAppArgs *FieldSystem_LaunchMailApp_Read(FieldSystem *fieldSystem, enum MailContext context, u8 param2, enum HeapID heapID) { - UnkStruct_02097728 *v0; + MailAppArgs *mailAppArgs; - if (param1 == 3) { - v0 = sub_020976F4(FieldSystem_GetSaveData(fieldSystem), param2, heapID); + if (context == MAIL_CONTEXT_CHECK) { + mailAppArgs = MailAppArgs_New_Check(FieldSystem_GetSaveData(fieldSystem), param2, heapID); } else { - v0 = sub_0209767C(FieldSystem_GetSaveData(fieldSystem), param1, param2, heapID); + mailAppArgs = MailAppArgs_New_ReadFromMailbox(FieldSystem_GetSaveData(fieldSystem), context, param2, heapID); } - sub_0203D910(fieldSystem, v0); + LaunchMailApp(fieldSystem, mailAppArgs); - return v0; + return mailAppArgs; } -UnkStruct_02097728 *sub_0203D984(FieldSystem *fieldSystem, Pokemon *param1, enum HeapID heapID) +MailAppArgs *FieldSystem_LaunchMailApp_ReadHeld(FieldSystem *fieldSystem, Pokemon *mon, enum HeapID heapID) { - UnkStruct_02097728 *v0 = sub_020976BC(FieldSystem_GetSaveData(fieldSystem), param1, heapID); - sub_0203D910(fieldSystem, v0); + MailAppArgs *mailAppArgs = MailAppArgs_New_ReadHeld(FieldSystem_GetSaveData(fieldSystem), mon, heapID); + LaunchMailApp(fieldSystem, mailAppArgs); - return v0; + return mailAppArgs; } static void OpenPoffinCaseApp(FieldSystem *fieldSystem, PoffinCaseAppData *poffinCaseAppData) diff --git a/src/unk_0205B33C.c b/src/unk_0205B33C.c index 6d613eee46..512e699f80 100644 --- a/src/unk_0205B33C.c +++ b/src/unk_0205B33C.c @@ -1208,7 +1208,7 @@ int sub_0205BF44(UnkStruct_0205B43C *param0, StringTemplate *param1) return 166; } - if (!sub_02014BBC(¶m0->unk_178)) { + if (!Sentence_IsValid(¶m0->unk_178)) { return 167; } @@ -1250,7 +1250,7 @@ static void sub_0205BFF0(UnkStruct_0205B4F8 *param0) void sub_0205C010(UnkStruct_0205B43C *param0, Sentence *param1) { - sub_02014CC0(¶m0->unk_178, param1); + Sentence_Set(¶m0->unk_178, param1); param0->unk_180 = 1; } diff --git a/src/unk_0205C22C.c b/src/unk_0205C22C.c index 43c532ffd2..3066d7b120 100644 --- a/src/unk_0205C22C.c +++ b/src/unk_0205C22C.c @@ -492,7 +492,7 @@ static void sub_0205C8DC(UnkStruct_0205C924 *param0) param0->unk_04 = NULL; param0->unk_08 = NULL; - sub_02014A9C(¶m0->unk_14, 0); + Sentence_InitWithType(¶m0->unk_14, 0); param0->unk_10 = 0; param0->unk_0C = 0; diff --git a/src/unk_020722AC.c b/src/unk_020722AC.c index 4d5e7d2577..4ed79051f4 100644 --- a/src/unk_020722AC.c +++ b/src/unk_020722AC.c @@ -1,9 +1,7 @@ #include #include -#include "struct_defs/mail.h" -#include "struct_defs/struct_02097728.h" - +#include "applications/mail.h" #include "applications/party_menu/defs.h" #include "applications/party_menu/main.h" #include "field/field_system.h" @@ -40,7 +38,6 @@ #include "system.h" #include "text.h" #include "unk_0203D1B8.h" -#include "unk_02097624.h" typedef struct { u8 unk_00; @@ -101,7 +98,7 @@ typedef struct { Window unk_184; Window unk_194; ScrollPrompts *unk_1A4; - UnkStruct_02097728 *unk_1A8; + MailAppArgs *unk_1A8; Mailbox *mailbox; Bag *bag; PartyMenu *partyMenu; @@ -908,7 +905,7 @@ static void sub_02072F30(UnkStruct_02072334 *param0, SaveData *saveData, enum He mail = Mail_New(heapID); for (i = 0; i < MAILBOX_SIZE; i++) { - sub_020284CC(mailbox, 0, i, mail); + Mailbox_GetMailAtSlot(mailbox, MAIL_CONTEXT_MAILBOX, i, mail); v7 = &(param0->unk_1C[i]); v8 = &(param0->unk_1C[param0->unk_19]); @@ -917,14 +914,14 @@ static void sub_02072F30(UnkStruct_02072334 *param0, SaveData *saveData, enum He v7->unk_00 = i; - if (!Mail_IsEmpty(mail)) { + if (!Mail_IsValid(mail)) { continue; } v7->unk_01 = 1; v7->trainerGender = Mail_GetTrainerGender(mail); v7->mailType = Mail_GetMailType(mail); - v7->item = Item_ForMailNumber(v7->mailType); + v7->item = Item_ForMailType(v7->mailType); String_CopyChars(v7->unk_08, Mail_GetTrainerName(mail)); @@ -967,7 +964,7 @@ static BOOL sub_02073060(UnkStruct_02072334 *param0) Bag_TryAddItem(param0->bag, v0->item, 1, param0->heapID); } - sub_02028470(param0->mailbox, 0, param0->unk_18); + Mailbox_ClearMailAtSlot(param0->mailbox, MAIL_CONTEXT_MAILBOX, param0->unk_18); sub_02073020(param0, param0->unk_18); sub_02072EB8(v0, param0->unk_18); @@ -989,7 +986,7 @@ static void sub_020730B8(UnkStruct_02072334 *param0, u8 param1, BOOL param2) v1 = SaveData_GetParty(FieldSystem_GetSaveData(param0->fieldSystem)); v2 = Party_GetPokemonBySlotIndex(v1, param1); - sub_020977E4(param0->mailbox, param0->unk_18, v2, param0->heapID); + Mail_TransferFromMailboxToMon(param0->mailbox, param0->unk_18, v2, param0->heapID); if (param2) { if (Bag_CanFitItem(param0->bag, v0->item, 1, param0->heapID)) { @@ -1234,9 +1231,9 @@ static int sub_020735E8(UnkStruct_02072334 *param0) switch (param0->unk_12) { case 0: if (param0->unk_1C[param0->unk_18].unk_01) { - param0->unk_1A8 = sub_0203D94C(param0->fieldSystem, 0, param0->unk_18, param0->heapID); + param0->unk_1A8 = FieldSystem_LaunchMailApp_Read(param0->fieldSystem, MAIL_CONTEXT_MAILBOX, param0->unk_18, param0->heapID); } else { - param0->unk_1A8 = sub_0203D920(param0->fieldSystem, 0, param0->unk_17, param0->unk_1C[param0->unk_18].mailType, param0->heapID); + param0->unk_1A8 = FieldSystem_LaunchMailApp_Write(param0->fieldSystem, MAIL_CONTEXT_MAILBOX, param0->unk_17, param0->unk_1C[param0->unk_18].mailType, param0->heapID); } param0->unk_12++; @@ -1246,16 +1243,16 @@ static int sub_020735E8(UnkStruct_02072334 *param0) break; } - if (sub_02097728(param0->unk_1A8)) { + if (MailApp_WasMailWritten(param0->unk_1A8)) { param0->unk_1C[param0->unk_18].unk_01 = 1; - sub_0209772C(param0->unk_1A8, 0, param0->unk_1C[param0->unk_18].unk_00); + MailApp_CopyWrittenMailToMailboxSlot(param0->unk_1A8, MAIL_CONTEXT_MAILBOX, param0->unk_1C[param0->unk_18].unk_00); v0 = 2; } else { v0 = 1; } - sub_02097770(param0->unk_1A8); + MailAppArgs_Free(param0->unk_1A8); param0->unk_12 = 0; return v0; } diff --git a/src/unk_0209747C.c b/src/unk_0209747C.c index 8b03d5f212..711422ee90 100644 --- a/src/unk_0209747C.c +++ b/src/unk_0209747C.c @@ -4,7 +4,6 @@ #include #include "struct_decls/struct_02014EC4_decl.h" -#include "struct_decls/struct_0209747C_decl.h" #include "struct_defs/sentence.h" #include "game_options.h" @@ -17,21 +16,6 @@ #include "unk_02014D38.h" #include "vars_flags.h" -struct UnkStruct_0209747C_t { - u8 unk_00; - u8 unk_01; - u8 unk_02; - u8 unk_03; - u8 unk_04; - u8 unk_05; - int unk_08; - const Pokedex *unk_0C; - const UnkStruct_02014EC4 *unk_10; - Sentence unk_14; - u16 unk_1C[2]; - u16 unk_20[2]; -}; - UnkStruct_0209747C *sub_0209747C(u32 param0, u32 param1, SaveData *saveData, enum HeapID heapID) { UnkStruct_0209747C *v0 = Heap_Alloc(heapID, sizeof(UnkStruct_0209747C)); @@ -47,7 +31,7 @@ UnkStruct_0209747C *sub_0209747C(u32 param0, u32 param1, SaveData *saveData, enu v0->unk_08 = Options_Frame(SaveData_GetOptions(saveData)); if (param0 == 2) { - sub_02014A9C(&v0->unk_14, 3); + Sentence_InitWithType(&v0->unk_14, 3); } else { int v1; @@ -114,7 +98,7 @@ void sub_02097534(const UnkStruct_0209747C *param0, u16 *param1) void sub_02097540(const UnkStruct_0209747C *param0, Sentence *param1) { - sub_02014CC0(param1, &(param0->unk_14)); + Sentence_Set(param1, &(param0->unk_14)); } u32 sub_02097550(const UnkStruct_0209747C *param0) diff --git a/src/unk_02097624.c b/src/unk_02097624.c deleted file mode 100644 index 40db43f3f3..0000000000 --- a/src/unk_02097624.c +++ /dev/null @@ -1,383 +0,0 @@ -#include -#include - -#include "constants/items.h" -#include "generated/game_records.h" -#include "generated/trainer_score_events.h" - -#include "struct_defs/mail.h" -#include "struct_defs/struct_02097728.h" -#include "struct_defs/struct_020978D8.h" - -#include "overlay020/ov20_021D0D80.h" -#include "overlay075/ov75_021D0D80.h" - -#include "game_records.h" -#include "heap.h" -#include "item.h" -#include "mail.h" -#include "overlay_manager.h" -#include "pokemon.h" -#include "save_player.h" -#include "savedata.h" -#include "string_gf.h" -#include "unk_02014A84.h" -#include "unk_0209747C.h" - -FS_EXTERN_OVERLAY(overlay20); -FS_EXTERN_OVERLAY(overlay75); - -typedef struct { - enum HeapID heapID; - u16 unk_04; - u16 unk_06; - void *unk_08; - ApplicationManager *appMan; - UnkStruct_020978D8 *unk_10; - Sentence unk_14; -} UnkStruct_02097944; - -static int sub_02097944(ApplicationManager *appMan, int *param1); -static int sub_020979A8(ApplicationManager *appMan, int *param1); -static int sub_02097AF8(ApplicationManager *appMan, int *param1); -BOOL sub_02097728(UnkStruct_02097728 *param0); -int sub_0209772C(UnkStruct_02097728 *param0, int param1, u8 param2); -int sub_02097750(UnkStruct_02097728 *param0, Pokemon *param1); -void sub_02097770(UnkStruct_02097728 *param0); -void sub_020978D8(UnkStruct_020978D8 *param0); -void sub_020978F0(Mail *param0, UnkStruct_020978D8 *param1); - -const ApplicationManagerTemplate Unk_020F64B0 = { - sub_02097944, - sub_020979A8, - sub_02097AF8, - 0xFFFFFFFF -}; - -UnkStruct_02097728 *sub_02097624(SaveData *saveData, int param1, u8 param2, u8 param3, enum HeapID heapID) -{ - UnkStruct_02097728 *v0; - int v2; - - Mailbox *mailbox = SaveData_GetMailbox(saveData); - v0 = Heap_AllocAtEnd(heapID, sizeof(UnkStruct_02097728)); - - MI_CpuClear8(v0, sizeof(UnkStruct_02097728)); - - v0->unk_0F = param3; - v0->unk_0E = param2; - v0->mailbox = mailbox; - v0->unk_00 = 1; - v0->unk_08 = param1; - v0->unk_0C = 0; - v0->saveData = saveData; - v0->unk_14 = Mail_New(heapID); - - Mail_Init(v0->unk_14); - sub_020281AC(v0->unk_14, 0xFFFF, param2, saveData); - - return v0; -} - -UnkStruct_02097728 *sub_0209767C(SaveData *saveData, int param1, u16 param2, enum HeapID heapID) -{ - UnkStruct_02097728 *v0 = Heap_AllocAtEnd(heapID, sizeof(UnkStruct_02097728)); - MI_CpuClear8(v0, sizeof(UnkStruct_02097728)); - - v0->unk_00 = 0; - v0->unk_08 = param1; - v0->unk_0C = param2; - v0->saveData = saveData; - - Mailbox *mailbox = SaveData_GetMailbox(saveData); - - v0->mailbox = mailbox; - v0->unk_14 = sub_020284A8(mailbox, param1, param2, heapID); - - return v0; -} - -UnkStruct_02097728 *sub_020976BC(SaveData *saveData, Pokemon *param1, enum HeapID heapID) -{ - UnkStruct_02097728 *v0 = Heap_AllocAtEnd(heapID, sizeof(UnkStruct_02097728)); - MI_CpuClear8(v0, sizeof(UnkStruct_02097728)); - - v0->unk_00 = 0; - v0->saveData = saveData; - v0->unk_14 = Mail_New(heapID); - - Pokemon_GetValue(param1, MON_DATA_MAIL, v0->unk_14); - return v0; -} - -UnkStruct_02097728 *sub_020976F4(SaveData *saveData, u8 param1, enum HeapID heapID) -{ - UnkStruct_02097728 *v0 = Heap_AllocAtEnd(heapID, sizeof(UnkStruct_02097728)); - MI_CpuClear8(v0, sizeof(UnkStruct_02097728)); - - v0->unk_00 = 0; - v0->saveData = saveData; - v0->unk_14 = Mail_New(heapID); - - Mail_SetMailType(v0->unk_14, param1); - return v0; -} - -BOOL sub_02097728(UnkStruct_02097728 *param0) -{ - return param0->unk_04; -} - -int sub_0209772C(UnkStruct_02097728 *param0, int param1, u8 param2) -{ - if (!sub_02097728(param0)) { - return 0; - } - - Mailbox_CopyMailToSlot(param0->mailbox, param1, param2, param0->unk_14); - return 1; -} - -int sub_02097750(UnkStruct_02097728 *param0, Pokemon *param1) -{ - if (!sub_02097728(param0)) { - return 0; - } - - Pokemon_SetValue(param1, MON_DATA_MAIL, param0->unk_14); - return 1; -} - -void sub_02097770(UnkStruct_02097728 *param0) -{ - if (param0->unk_14 != NULL) { - Heap_Free(param0->unk_14); - } - - Heap_Free(param0); -} - -int sub_02097788(Mailbox *mailbox, Pokemon *mon, enum HeapID heapID) -{ - int item = ITEM_NONE; - int slot = Mail_GetEmptySlotInArray(mailbox, 0); - - if (slot == 0xFFFFFFFF) { - return 0xFFFFFFFF; - } - - Mail *mail = Mail_New(heapID); - - Pokemon_GetValue(mon, MON_DATA_MAIL, mail); - Mailbox_CopyMailToSlot(mailbox, 0, slot, mail); - Mail_Init(mail); - Pokemon_SetValue(mon, MON_DATA_MAIL, mail); - Pokemon_SetValue(mon, MON_DATA_HELD_ITEM, &item); - Heap_Free(mail); - - return slot; -} - -int sub_020977E4(Mailbox *mailbox, u16 param1, Pokemon *mon, enum HeapID heapID) -{ - int item = 0; - Mail *mail = sub_020284A8(mailbox, 0, param1, heapID); - - if (mail == NULL) { - return 0xFFFFFFFF; - } - - item = Item_ForMailNumber(Mail_GetMailType(mail)); - - Pokemon_SetValue(mon, MON_DATA_MAIL, mail); - Pokemon_SetValue(mon, MON_DATA_HELD_ITEM, &item); - sub_02028470(mailbox, 0, param1); - Heap_Free(mail); - - return param1; -} - -static UnkStruct_020978D8 *sub_02097834(const Mail *mail, enum HeapID heapID) -{ - u16 i; - UnkStruct_020978D8 *v1 = Heap_Alloc(heapID, sizeof(UnkStruct_020978D8)); - MI_CpuClear8(v1, sizeof(UnkStruct_020978D8)); - - v1->unk_00 = 0; - v1->unk_08 = Mail_GetTrainerID(mail); - v1->unk_10 = String_Init(8, heapID); - - String_CopyChars(v1->unk_10, Mail_GetTrainerName((Mail *)mail)); - - v1->mailType = Mail_GetMailType(mail); - v1->language = Mail_GetLanguage(mail); - v1->gameVersion = Mail_GetGameVersion(mail); - - for (i = 0; i < 3; i++) { - v1->unk_14[i].val2 = sub_02028328(mail, i, 2, sub_02028408(mail)); - } - - for (i = 0; i < 3; i++) { - sub_02014CC0(&v1->unk_1A[i], sub_0202840C((Mail *)mail, i)); - } - - return v1; -} - -void sub_020978D8(UnkStruct_020978D8 *param0) -{ - if (param0->unk_10 != NULL) { - String_Free(param0->unk_10); - } - - Heap_Free(param0); -} - -void sub_020978F0(Mail *param0, UnkStruct_020978D8 *param1) -{ - u16 v0; - - for (v0 = 0; v0 < 3; v0++) { - sub_0202841C(param0, ¶m1->unk_1A[v0], v0); - } - - Mail_SetMailType(param0, param1->mailType); -} - -static BOOL sub_02097920(ApplicationManager **appManPtr) -{ - if (*appManPtr) { - if (ApplicationManager_Exec(*appManPtr)) { - ApplicationManager_Free(*appManPtr); - *appManPtr = NULL; - return 1; - } - } - - return 0; -} - -static int sub_02097944(ApplicationManager *appMan, int *param1) -{ - UnkStruct_02097944 *v0 = NULL; - UnkStruct_02097728 *v1 = (UnkStruct_02097728 *)ApplicationManager_Args(appMan); - - Heap_Create(HEAP_ID_APPLICATION, HEAP_ID_40, 0x1000); - v0 = ApplicationManager_NewData(appMan, sizeof(UnkStruct_02097944), HEAP_ID_40); - MI_CpuClear8(v0, sizeof(UnkStruct_02097944)); - - v0->heapID = HEAP_ID_40; - v0->unk_10 = sub_02097834(v1->unk_14, v0->heapID); - v0->unk_10->options = SaveData_GetOptions(v1->saveData); - - if (v1->unk_00 == 1) { - v0->unk_10->mailType = v1->unk_0F; - } - - if (v0->unk_10->mailType >= NUM_MAILS) { - v0->unk_10->mailType = 0; - } - - v0->unk_10->unk_00 = v1->unk_00; - - return 1; -} - -static int sub_020979A8(ApplicationManager *appMan, int *param1) -{ - UnkStruct_02097944 *v0 = ApplicationManager_Data(appMan); - UnkStruct_02097728 *v1 = (UnkStruct_02097728 *)ApplicationManager_Args(appMan); - - FS_EXTERN_OVERLAY(overlay75); - FS_EXTERN_OVERLAY(overlay20); - - static const ApplicationManagerTemplate v2 = { - ov75_021D0D80, - ov75_021D0DF8, - ov75_021D0E10, - FS_OVERLAY_ID(overlay75), - }; - static const ApplicationManagerTemplate v3 = { - ov20_021D0D80, - ov20_021D0DF8, - ov20_021D0EA8, - FS_OVERLAY_ID(overlay20), - }; - - switch (*param1) { - case 0: - v0->unk_10->unk_00 = v1->unk_00; - v0->appMan = ApplicationManager_New(&v2, v0->unk_10, v0->heapID); - *param1 = 1; - break; - case 1: - if (!sub_02097920(&v0->appMan)) { - break; - } - - switch (v0->unk_10->unk_00) { - case 0xFFFF: - *param1 = 2; - break; - case 3: - *param1 = 2; - break; - default: - *param1 = 3; - break; - } - break; - case 2: - if (v1->unk_00 == 1) { - if (v0->unk_10->unk_00 == 3) { - sub_020978F0(v1->unk_14, v0->unk_10); - - GameRecords_IncrementTrainerScore(SaveData_GetGameRecords(v1->saveData), TRAINER_SCORE_EVENT_UNK_02); - GameRecords_IncrementRecordValue(SaveData_GetGameRecords(v1->saveData), RECORD_UNK_045); - v1->unk_04 = 1; - } else { - v1->unk_04 = 0; - } - } - - return 1; - case 3: - v0->unk_08 = sub_0209747C(2, 0, v1->saveData, v0->heapID); - - if (sub_02014BBC(&(v0->unk_10->unk_1A[v0->unk_10->unk_02]))) { - sub_02014CC0(&(v0->unk_14), &(v0->unk_10->unk_1A[v0->unk_10->unk_02])); - } else { - sub_02014A9C(&(v0->unk_14), 3); - } - - sub_02097500(v0->unk_08, &(v0->unk_14)); - v0->appMan = ApplicationManager_New(&v3, v0->unk_08, v0->heapID); - *param1 = 4; - break; - case 4: - if (!sub_02097920(&v0->appMan)) { - break; - } - - if (sub_02097528(v0->unk_08) == 0) { - sub_02097540(v0->unk_08, &(v0->unk_10->unk_1A[v0->unk_10->unk_02])); - } - - sub_020974EC(v0->unk_08); - *param1 = 0; - break; - } - - return 0; -} - -static int sub_02097AF8(ApplicationManager *appMan, int *param1) -{ - UnkStruct_02097944 *v0 = ApplicationManager_Data(appMan); - - sub_020978D8(v0->unk_10); - ApplicationManager_FreeData(appMan); - Heap_Destroy(v0->heapID); - - return 1; -} diff --git a/src/unk_020998EC.c b/src/unk_020998EC.c index 8ec40683e2..72e6cc61f4 100644 --- a/src/unk_020998EC.c +++ b/src/unk_020998EC.c @@ -5,7 +5,6 @@ #include "struct_decls/struct_02014D38_decl.h" #include "struct_decls/struct_02014EC4_decl.h" -#include "struct_decls/struct_0209747C_decl.h" #include "struct_decls/struct_020998EC_decl.h" #include "heap.h" diff --git a/src/unk_0209ACF4.c b/src/unk_0209ACF4.c index 7c3adee4ab..f48cd18231 100644 --- a/src/unk_0209ACF4.c +++ b/src/unk_0209ACF4.c @@ -3,7 +3,6 @@ #include #include -#include "struct_decls/struct_0209747C_decl.h" #include "struct_defs/sentence.h" #include "field/field_system.h" @@ -136,19 +135,19 @@ static BOOL sub_0209AE14(FieldTask *param0) switch (v0->unk_64) { case 0: - sub_02014CC0(&(v0->unk_48), sub_0202D498(v0->fieldSystem->saveData, 0)); + Sentence_Set(&(v0->unk_48), sub_0202D498(v0->fieldSystem->saveData, 0)); v0->unk_54 = 3; break; case 1: - sub_02014CC0(&(v0->unk_48), sub_0202D498(v0->fieldSystem->saveData, 1)); + Sentence_Set(&(v0->unk_48), sub_0202D498(v0->fieldSystem->saveData, 1)); v0->unk_54 = 3; break; case 2: - sub_02014CC0(&(v0->unk_48), sub_0202D498(v0->fieldSystem->saveData, 2)); + Sentence_Set(&(v0->unk_48), sub_0202D498(v0->fieldSystem->saveData, 2)); v0->unk_54 = 3; break; case 3: - sub_02014CC0(&(v0->unk_48), sub_0202D498(v0->fieldSystem->saveData, 3)); + Sentence_Set(&(v0->unk_48), sub_0202D498(v0->fieldSystem->saveData, 3)); v0->unk_54 = 3; break; case 4: diff --git a/src/unk_0209B344.c b/src/unk_0209B344.c index 4642bb1a77..886830b6d0 100644 --- a/src/unk_0209B344.c +++ b/src/unk_0209B344.c @@ -3,7 +3,6 @@ #include #include -#include "struct_decls/struct_0209747C_decl.h" #include "struct_defs/sentence.h" #include "field/field_system.h" @@ -43,7 +42,7 @@ void sub_0209B344(FieldTask *param0, u16 *param1) v1->unk_14 = SaveData_MiscSaveBlock(fieldSystem->saveData); v1->unk_20 = param1; - sub_02014A9C(&v1->unk_08, 4); + Sentence_InitWithType(&v1->unk_08, 4); MiscSaveBlock_IntroMsg(v1->unk_14, &v1->unk_08); sub_02097520(v1->unk_10);