summaryrefslogtreecommitdiff
path: root/arm9/src
diff options
context:
space:
mode:
Diffstat (limited to 'arm9/src')
-rw-r--r--arm9/src/hall_of_fame.c147
-rw-r--r--arm9/src/pokemon.c8
-rw-r--r--arm9/src/poketch.c262
-rw-r--r--arm9/src/save_arrays.c19
4 files changed, 420 insertions, 16 deletions
diff --git a/arm9/src/hall_of_fame.c b/arm9/src/hall_of_fame.c
new file mode 100644
index 00000000..7cc1c0f2
--- /dev/null
+++ b/arm9/src/hall_of_fame.c
@@ -0,0 +1,147 @@
+#include "global.h"
+#include "pokemon.h"
+#include "save_block_2.h"
+#include "MI_memory.h"
+#include "party.h"
+#include "string16.h"
+#include "RTC_api.h"
+#include "hall_of_fame.h"
+
+#pragma thumb on
+
+u32 Sav2_HOF_sizeof(void)
+{
+ return sizeof(struct HallOfFame);
+}
+
+void Sav2_HOF_init(struct HallOfFame * hof)
+{
+ MI_CpuClear32(hof, sizeof(struct HallOfFame));
+}
+
+void Sav2_HOF_RecordParty(struct HallOfFame * hof, struct PlayerParty * party, RTCDate * date)
+{
+ GF_ASSERT(hof != NULL);
+ GF_ASSERT(hof->next_record < NUM_HOF_RECORDS);
+ if (hof->num_total < 9999)
+ {
+ struct HOFParty * hof_party = &hof->parties[hof->next_record];
+ int nmons = GetPartyCount(party);
+ struct String * str = String_ctor(POKEMON_NAME_LENGTH + 1, 0);
+ MI_CpuClear16(hof_party->party, 6 * sizeof(struct HOFMon));
+ int i, j;
+ for (i = 0, j = 0; i < nmons; i++)
+ {
+ struct Pokemon * mon = GetPartyMonByIndex(party, i);
+ BOOL lock = AcquireMonLock(mon);
+ if (!GetMonData(mon, MON_DATA_IS_EGG, NULL))
+ {
+ hof_party->party[j].species = (u16)GetMonData(mon, MON_DATA_SPECIES, NULL);
+ hof_party->party[j].level = (u8)GetMonData(mon, MON_DATA_LEVEL, NULL);
+ hof_party->party[j].forme = (u8)GetMonData(mon, MON_DATA_FORME, NULL);
+ hof_party->party[j].personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL);
+ hof_party->party[j].otid = GetMonData(mon, MON_DATA_OTID, NULL);
+ hof_party->party[j].moves[0] = (u16)GetMonData(mon, MON_DATA_MOVE1, NULL);
+ hof_party->party[j].moves[1] = (u16)GetMonData(mon, MON_DATA_MOVE2, NULL);
+ hof_party->party[j].moves[2] = (u16)GetMonData(mon, MON_DATA_MOVE3, NULL);
+ hof_party->party[j].moves[3] = (u16)GetMonData(mon, MON_DATA_MOVE4, NULL);
+ if (str != NULL)
+ {
+ GetMonData(mon, MON_DATA_NICKNAME_3, str);
+ CopyStringToU16Array(str, hof_party->party[j].nickname, POKEMON_NAME_LENGTH + 1);
+ GetMonData(mon, MON_DATA_OT_NAME_2, str);
+ CopyStringToU16Array(str, hof_party->party[j].otname, OT_NAME_LENGTH + 1);
+ }
+ else
+ {
+ hof_party->party[j].nickname[0] = EOS;
+ hof_party->party[j].otname[0] = EOS;
+ }
+ j++;
+ }
+ ReleaseMonLock(mon, lock);
+ }
+ hof_party->year = (u16)date->year;
+ hof_party->month = (u8)date->month;
+ hof_party->day = (u8)date->day;
+ hof->next_record++;
+ if (hof->next_record >= NUM_HOF_RECORDS)
+ hof->next_record = 0;
+ hof->num_total++;
+ if (str != NULL)
+ String_dtor(str);
+ }
+}
+
+u32 Sav2_HOF_GetNumRecords(struct HallOfFame * hof)
+{
+ GF_ASSERT(hof != NULL);
+ GF_ASSERT(hof->next_record < NUM_HOF_RECORDS);
+ if (hof->num_total < NUM_HOF_RECORDS)
+ return hof->num_total;
+ else
+ return NUM_HOF_RECORDS;
+}
+
+int Sav2_HOF_TranslateRecordIdx(struct HallOfFame * hof, int a1)
+{
+ GF_ASSERT(hof != NULL);
+ GF_ASSERT(hof->next_record < NUM_HOF_RECORDS);
+ GF_ASSERT(a1 < NUM_HOF_RECORDS);
+ return (int)(hof->num_total - a1);
+}
+
+u32 Sav2_HOF_RecordCountMons(struct HallOfFame * hof, int a1)
+{
+ GF_ASSERT(hof != NULL);
+ GF_ASSERT(hof->next_record < NUM_HOF_RECORDS);
+ GF_ASSERT(a1 < NUM_HOF_RECORDS);
+ int hofno = (int)(hof->next_record - 1 - a1);
+ if (hofno < 0)
+ hofno += NUM_HOF_RECORDS;
+ struct HOFParty * hof_party = &hof->parties[hofno];
+ u32 i;
+ for (i = 0; i < 6; i++)
+ {
+ if (hof_party->party[i].species == SPECIES_NONE)
+ break;
+ }
+ return i;
+}
+
+void Sav2_HOF_GetMonStatsByIndexPair(struct HallOfFame * hof, int a1, int a2, struct HofDisplayMon * dest)
+{
+ GF_ASSERT(hof != NULL);
+ GF_ASSERT(hof->next_record < NUM_HOF_RECORDS);
+ GF_ASSERT(a1 < NUM_HOF_RECORDS);
+ int hofno = (int)(hof->next_record - 1 - a1);
+ if (hofno < 0)
+ hofno += NUM_HOF_RECORDS;
+ struct HOFMon * mon = &hof->parties[hofno].party[a2];
+ dest->species = mon->species;
+ dest->level = mon->level;
+ dest->personality = mon->personality;
+ dest->otid = mon->otid;
+ dest->forme = mon->forme;
+ CopyU16ArrayToString(dest->nickname, mon->nickname);
+ CopyU16ArrayToString(dest->otname, mon->otname);
+ for (int i = 0; i < 4; i++)
+ {
+ dest->moves[i] = mon->moves[i];
+ }
+}
+
+void Sav2_HOF_GetClearDate(struct HallOfFame * hof, int a1, RTCDate * dest)
+{
+ GF_ASSERT(hof != NULL);
+ GF_ASSERT(hof->next_record < NUM_HOF_RECORDS);
+ GF_ASSERT(a1 < NUM_HOF_RECORDS);
+ int hofno = (int)(hof->next_record - 1 - a1);
+ if (hofno < 0)
+ hofno += NUM_HOF_RECORDS;
+ struct HOFParty *party = &hof->parties[hofno];
+ dest->year = party->year;
+ dest->month = party->month;
+ dest->day = party->day;
+ dest->week = RTC_WEEK_SUNDAY;
+}
diff --git a/arm9/src/pokemon.c b/arm9/src/pokemon.c
index 97be796b..347cb5ac 100644
--- a/arm9/src/pokemon.c
+++ b/arm9/src/pokemon.c
@@ -58,7 +58,7 @@ u16 MonEncryptionLCRNG(u32 * seed);
u16 CalcMonChecksum(u16 * datap, u32 size);
PokemonDataBlock * GetSubstruct(struct BoxPokemon * boxmon, u32 personality, u8 which_struct);
void LoadMonBaseStats_HandleAlternateForme(int species, int forme, struct BaseStats * baseStats);
-u8 FUN_020690D4(struct BoxPokemon * boxmon);
+u8 GetBoxMonUnownLetter(struct BoxPokemon * boxmon);
#define ENCRY_ARGS_PTY(mon) (u16 *)&(mon)->party, sizeof((mon)->party), (mon)->box.pid
#define ENCRY_ARGS_BOX(boxmon) (u16 *)&(boxmon)->substructs, sizeof((boxmon)->substructs), (boxmon)->checksum
@@ -2458,12 +2458,12 @@ u32 FUN_020690C8(void)
return sizeof(struct BoxPokemon);
}
-u8 FUN_020690CC(struct Pokemon * pokemon)
+u8 GetMonUnownLetter(struct Pokemon * pokemon)
{
- return FUN_020690D4(&pokemon->box);
+ return GetBoxMonUnownLetter(&pokemon->box);
}
-u8 FUN_020690D4(struct BoxPokemon * boxmon)
+u8 GetBoxMonUnownLetter(struct BoxPokemon * boxmon)
{
return (u8)GetBoxMonData(boxmon, MON_DATA_FORME, NULL);
}
diff --git a/arm9/src/poketch.c b/arm9/src/poketch.c
new file mode 100644
index 00000000..54dff12b
--- /dev/null
+++ b/arm9/src/poketch.c
@@ -0,0 +1,262 @@
+#include "global.h"
+#include "MI_memory.h"
+#include "pokemon.h"
+#include "poketch.h"
+
+#pragma thumb on
+
+extern u16 BoxMon_GetAlternateForme(struct BoxPokemon * mon);
+
+static const u8 sMarkingMapInitialPos[][2] = {
+ { 0x68, 0x98 },
+ { 0x78, 0x98 },
+ { 0x88, 0x98 },
+ { 0x98, 0x98 },
+ { 0xA8, 0x98 },
+ { 0xB8, 0x98 },
+};
+
+u32 Sav2_Poketch_sizeof(void)
+{
+ return sizeof(struct SavePoketch);
+}
+
+void Sav2_Poketch_init(struct SavePoketch * poketch)
+{
+ int i;
+
+ for (i = 0; i < 32; i++)
+ {
+ poketch->unlockedApps[i] = 0;
+ }
+ poketch->numApps = 0;
+ poketch->selectedApp = 0;
+ poketch->isGiven = 0;
+ poketch->color = 0;
+ poketch->pedometerActive = 0;
+ poketch->stepCounter = 0;
+ poketch->alarmActive = 0;
+ poketch->alarmHour = 0;
+ poketch->alarmMinute = 0;
+ poketch->calendarMonth = 1; // January
+ poketch->calendarFlags = 0;
+ for (i = 0; i < 6; i++)
+ {
+ poketch->markingMapPos[i][0] = sMarkingMapInitialPos[i][0];
+ poketch->markingMapPos[i][1] = sMarkingMapInitialPos[i][1];
+ }
+ for (i = 0; i < 12; i++)
+ {
+ poketch->pokemonHistory[i][0] = SPECIES_NONE;
+ poketch->pokemonHistory[i][1] = 0;
+ }
+ poketch->dotArtistEnabled = 0;
+ Sav2_Poketch_UnlockApp(poketch, POKETCH_DIGITAL_WATCH);
+}
+
+void Sav2_Poketch_Give(struct SavePoketch * poketch)
+{
+ poketch->isGiven = TRUE;
+}
+
+BOOL Sav2_Poketch_IsGiven(struct SavePoketch * poketch)
+{
+ return poketch->isGiven;
+}
+
+u8 Sav2_Poketch_AppIsUnlocked(struct SavePoketch * poketch, PoketchApp app)
+{
+ return poketch->unlockedApps[app];
+}
+
+BOOL Sav2_Poketch_UnlockApp(struct SavePoketch * poketch, PoketchApp app)
+{
+ GF_ASSERT(app >= FIRST_POKETCH_APP_ID && app < NUM_POKETCH_APPS);
+ if (poketch->numApps < NUM_POKETCH_APPS && !poketch->unlockedApps[app])
+ {
+ poketch->unlockedApps[app] = TRUE;
+ poketch->numApps++;
+ if (app == POKETCH_PEDOMETER) // pedometer
+ {
+ poketch->pedometerActive = TRUE;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+PoketchApp Sav2_Poketch_GetSelectedApp(struct SavePoketch * poketch)
+{
+ return (PoketchApp)poketch->selectedApp;
+}
+
+PoketchApp Sav2_Poketch_CycleNextApp(struct SavePoketch * poketch)
+{
+ PoketchApp app = (PoketchApp)poketch->selectedApp;
+ PoketchApp prev = app;
+
+ while (1)
+ {
+ if (++app >= NUM_POKETCH_APPS)
+ app = FIRST_POKETCH_APP_ID;
+ if (app == prev)
+ break;
+ if (poketch->unlockedApps[app])
+ break;
+ }
+ poketch->selectedApp = (s8)app;
+ return (PoketchApp)poketch->selectedApp;
+}
+
+u8 Sav2_Poketch_GetScreenTint(struct SavePoketch * poketch)
+{
+ GF_ASSERT(poketch != NULL);
+ return poketch->color;
+}
+
+void Sav2_Poketch_SetScreenTint(struct SavePoketch * poketch, u32 color)
+{
+ GF_ASSERT(poketch != NULL);
+ GF_ASSERT(color < 8);
+ poketch->color = (u8)color;
+}
+
+u32 Sav2_Poketch_GetStepCounter(struct SavePoketch * poketch)
+{
+ return poketch->stepCounter;
+}
+
+void Sav2_Poketch_SetStepCounter(struct SavePoketch * poketch, u32 steps)
+{
+ if (poketch->pedometerActive)
+ poketch->stepCounter = steps;
+}
+
+BOOL Sav2_Poketch_GetAlarmState(struct SavePoketch * poketch)
+{
+ return poketch->alarmActive;
+}
+
+void Sav2_Poketch_GetAlarmSetTime(struct SavePoketch * poketch, u32 * hour_p, u32 * min_p)
+{
+ *hour_p = poketch->alarmHour;
+ *min_p = poketch->alarmMinute;
+}
+
+void Sav2_Poketch_SetAlarm(struct SavePoketch * poketch, BOOL enabled, u32 hour, u32 minute)
+{
+ poketch->alarmActive = enabled;
+ poketch->alarmHour = hour;
+ poketch->alarmMinute = minute;
+}
+
+void Sav2_Poketch_CalendarDateHighlight(struct SavePoketch * poketch, u32 month, u32 day)
+{
+ if (poketch->calendarMonth == month)
+ {
+ poketch->calendarFlags |= (1u << (day - 1));
+ }
+ else
+ {
+ poketch->calendarMonth = (u8)month;
+ poketch->calendarFlags = (1u << (day - 1));
+ }
+}
+
+void Sav2_Poketch_CalendarDateUnhighlight(struct SavePoketch * poketch, u32 month, u32 day)
+{
+ if (poketch->calendarMonth == month)
+ {
+ poketch->calendarFlags &= ~(1u << (day - 1));
+ }
+ else
+ {
+ poketch->calendarMonth = (u8)month;
+ poketch->calendarFlags = 0;
+ }
+}
+
+BOOL Sav2_Poketch_CalendarDateIsHighlighted(struct SavePoketch * poketch, u32 month, u32 day)
+{
+ if (poketch->calendarMonth == month)
+ {
+ return (BOOL)((poketch->calendarFlags >> (day - 1)) & 1);
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+void Sav2_Poketch_MarkingMapSetPos(struct SavePoketch * poketch, s32 mark, u8 x, u8 y)
+{
+ GF_ASSERT(mark < 6);
+ poketch->markingMapPos[mark][0] = x;
+ poketch->markingMapPos[mark][1] = y;
+}
+
+void Sav2_Poketch_MarkingMapGetPos(struct SavePoketch * poketch, s32 mark, u8 * x_p, u8 * y_p)
+{
+ GF_ASSERT(mark < 6);
+ *x_p = poketch->markingMapPos[mark][0];
+ *y_p = poketch->markingMapPos[mark][1];
+}
+
+u32 Sav2_Poketch_DotArtistIsEnabled(struct SavePoketch * poketch)
+{
+ return poketch->dotArtistEnabled;
+}
+
+void Sav2_Poketch_DotArtistGetDrawing(struct SavePoketch * poketch, void * grid)
+{
+ if (poketch->dotArtistEnabled)
+ {
+ MI_CpuCopy8(poketch->dotArtistGrid, grid, DOT_ARTIST_SIZE);
+ }
+}
+
+void Sav2_Poketch_DotArtistSetDrawingAndEnable(struct SavePoketch * poketch, void * grid)
+{
+ MI_CpuCopy8(grid, poketch->dotArtistGrid, DOT_ARTIST_SIZE);
+ poketch->dotArtistEnabled = TRUE;
+}
+
+void Sav2_Poketch_PokemonHistoryAddMon(struct SavePoketch * poketch, struct BoxPokemon * mon)
+{
+ int i = Sav2_Poketch_PokemonHistoryGetFirstEmptySlot(poketch);
+ if (i >= 12)
+ {
+ for (i = 0; i < 11; i++)
+ {
+ poketch->pokemonHistory[i][0] = poketch->pokemonHistory[i + 1][0];
+ poketch->pokemonHistory[i][1] = poketch->pokemonHistory[i + 1][1];
+ }
+ i = 11;
+ }
+ poketch->pokemonHistory[i][0] = (u16)GetBoxMonData(mon, MON_DATA_SPECIES, NULL);
+ poketch->pokemonHistory[i][1] = BoxMon_GetAlternateForme(mon);
+}
+
+int Sav2_Poketch_PokemonHistoryGetFirstEmptySlot(struct SavePoketch * poketch)
+{
+ int i;
+ for (i = 0; i < 12; i++)
+ {
+ if (poketch->pokemonHistory[i][0] == SPECIES_NONE)
+ return i;
+ }
+ return i;
+}
+
+void Sav2_Poketch_PokemonHistoryGetSlotN(struct SavePoketch * poketch, s32 i, u32 * species_p, u32 * forme_p)
+{
+ GF_ASSERT(i < 12);
+ GF_ASSERT(poketch->pokemonHistory[i][0] != SPECIES_NONE);
+ *species_p = poketch->pokemonHistory[i][0];
+ *forme_p = poketch->pokemonHistory[i][1];
+}
+
+struct SavePoketch * Sav2_Poketch_get(struct SaveBlock2 * sav2)
+{
+ return (struct SavePoketch *)SavArray_get(sav2, 5);
+}
diff --git a/arm9/src/save_arrays.c b/arm9/src/save_arrays.c
index 58e1ff4c..797539d2 100644
--- a/arm9/src/save_arrays.c
+++ b/arm9/src/save_arrays.c
@@ -4,11 +4,13 @@
#include "save_block_2.h"
#include "party.h"
#include "event_data.h"
+#include "pokemon_storage_system.h"
+#include "sav_system_info.h"
+#include "poketch.h"
+#include "hall_of_fame.h"
+#include "unk_020286F8.h"
-extern u32 FUN_0202B034(void);
extern u32 FUN_0202AC20(void);
-extern u32 Sav2_SysInfo_sizeof(void);
-extern u32 FUN_0204BE14(void);
extern u32 FUN_02034D7C(void);
extern u32 FUN_02023D64(void);
extern u32 FUN_02023C40(void);
@@ -20,7 +22,6 @@ extern u32 FUN_02023AC8(void);
extern u32 FUN_02026FD8(void);
extern u32 FUN_02025844(void);
extern u32 FUN_02028054(void);
-extern u32 FUN_020286F8(void);
extern u32 FUN_02028980(void);
extern u32 FUN_02029A84(void);
extern u32 FUN_02029FB0(void);
@@ -37,11 +38,7 @@ extern u32 FUN_02029AE0(void);
extern u32 FUN_0202BE98(void);
extern u32 FUN_0202C0E0(void);
extern u32 FUN_02013B28(void);
-extern u32 PCStorage_sizeof(void);
-extern void FUN_0202B03C(void *);
extern void FUN_0202AC28(void *);
-extern void Sav2_SysInfo_init(void *);
-extern void FUN_0204BE18(void *);
extern void FUN_02034D98(void *);
extern void FUN_02024378(void *);
extern void FUN_02023C48(void *);
@@ -53,7 +50,6 @@ extern void FUN_02023AD8(void *);
extern void FUN_02026F60(void *);
extern void FUN_0202584C(void *);
extern void FUN_0202805C(void *);
-extern void FUN_02028724(void *);
extern void FUN_02028994(void *);
extern void FUN_02029A8C(void *);
extern void FUN_02029FB8(void *);
@@ -70,10 +66,9 @@ extern void FUN_02029AE8(void *);
extern void FUN_0202BEA0(void *);
extern void FUN_0202C0E4(void *);
extern void FUN_02013B2C(void *);
-extern void PCStorage_init(void *);
const struct SaveChunkHeader UNK_020EE6E0[] = {
- { 0, 32, (SAVSIZEFN)FUN_0202B034, (SAVINITFN)FUN_0202B03C },
+ { 0, 32, (SAVSIZEFN)Sav2_HOF_sizeof, (SAVINITFN)Sav2_HOF_init },
{ 1, 35, (SAVSIZEFN)FUN_0202AC20, (SAVINITFN)FUN_0202AC28 }
};
@@ -83,7 +78,7 @@ const struct SaveChunkHeader UNK_020EE700[] = {
{ 2, 0, (SAVSIZEFN)SavArray_Party_sizeof, (SAVINITFN)SavArray_Party_init },
{ 3, 0, (SAVSIZEFN)Sav2_Bag_sizeof, (SAVINITFN)Sav2_Bag_init },
{ 4, 0, (SAVSIZEFN)SavArray_Flags_sizeof, (SAVINITFN)SavArray_Flags_init },
- { 5, 0, (SAVSIZEFN)FUN_0204BE14, (SAVINITFN)FUN_0204BE18 },
+ { 5, 0, (SAVSIZEFN)Sav2_Poketch_sizeof, (SAVINITFN)Sav2_Poketch_init },
{ 6, 0, (SAVSIZEFN)FUN_02034D7C, (SAVINITFN)FUN_02034D98 },
{ 7, 0, (SAVSIZEFN)FUN_02023D64, (SAVINITFN)FUN_02024378 },
{ 8, 0, (SAVSIZEFN)FUN_02023C40, (SAVINITFN)FUN_02023C48 },