Document record rankings machine (#977)
Some checks failed
build / build (push) Has been cancelled

This commit is contained in:
Viperio 2026-03-13 16:14:11 +01:00 committed by GitHub
parent 72bc375671
commit 3d24f842f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
35 changed files with 1580 additions and 1568 deletions

View File

@ -2503,9 +2503,9 @@
.short \arg0
.endm
.macro ScrCmd_1B5 listIndex
.macro StartRankingsMachine machineID
.short 437
.short \listIndex
.short \machineID
.endm
.macro GetTimeOfDay destVarID

View File

@ -13,7 +13,7 @@ RECORD_EGGS_HATCHED
RECORD_POKEMON_EVOLVED
RECORD_UNK_013
RECORD_UNK_014
RECORD_UNK_015
RECORD_BATTLE_TOWER_CHALLENGES
RECORD_UNK_016
RECORD_UNK_017
RECORD_UNK_018
@ -27,7 +27,7 @@ RECORD_UNK_025
RECORD_WIFI_BATTLE_WINS
RECORD_WIFI_BATTLE_LOSSES
RECORD_UNK_028
RECORD_UNK_029
RECORD_BATTLE_TOWER_VICTORIES
RECORD_UNK_030
RECORD_UNK_031
RECORD_UNK_032
@ -88,11 +88,11 @@ RECORD_UNK_086
RECORD_UNK_087
RECORD_UNK_088
RECORD_UNK_089
RECORD_UNK_090
RECORD_UNK_091
RECORD_SUPER_CONTEST_PARTICIPATIONS
RECORD_LINK_CONTEST_PARTICIPATIONS
RECORD_SUPER_CONTEST_WINS
RECORD_LINK_CONTEST_WINS
RECORD_UNK_094
RECORD_RIBBONS_WON
RECORD_USED_INEFFECTIVE_MOVE
RECORD_FAINTED_ENEMY_MON
RECORD_ATTACKED_ALLY

View File

@ -530,7 +530,7 @@ TEXT_BANK_ROUTE_228_GATE_TO_ROUTE_226
TEXT_BANK_ROUTE_228_NORTH_HOUSE
TEXT_BANK_ROUTE_228_SOUTH_HOUSE
TEXT_BANK_ROUTE_229
TEXT_BANK_UNK_0532
TEXT_BANK_RANKINGS_MACHINE
TEXT_BANK_UNK_0533
TEXT_BANK_SAVE_INFO_WINDOW
TEXT_BANK_RIBBON_NAMES

View File

@ -82,7 +82,7 @@ enum HeapID {
HEAP_ID_GAME_START,
HEAP_ID_MIGRATE_FROM_GBA,
HEAP_ID_79,
HEAP_ID_80,
HEAP_ID_RANKINGS_MACHINE,
HEAP_ID_MAIN_MENU,
HEAP_ID_ROWAN_INTRO,
HEAP_ID_ROWAN_INTRO_TV,
@ -160,6 +160,7 @@ enum HeapSize {
HEAP_SIZE_BOAT_CUTSCENE = 0x20000,
HEAP_SIZE_EVOLUTION = 0x30000,
HEAP_SIZE_GAME_START = 0x20000,
HEAP_SIZE_RECORD_LIST = 0x6000,
HEAP_SIZE_MAIN_MENU = 0x40000,
HEAP_SIZE_MIGRATE_FROM_GBA = 0x38000,
HEAP_SIZE_WONDER_CARDS_APP = 0x30000,

54
include/rankings.h Normal file
View File

@ -0,0 +1,54 @@
#ifndef POKEPLATINUM_RANKINGS_H
#define POKEPLATINUM_RANKINGS_H
#include "constants/heap.h"
#include "constants/string.h"
#include "savedata.h"
#include "string_gf.h"
#define MAX_RANKINGS_ENTRIES 6
#define RECORDS_WITH_RANKINGS_COUNT 13
typedef struct RankingEntry {
u32 seed;
u32 recordValue;
u16 playerName[TRAINER_NAME_LEN + 1];
} RankingEntry;
typedef struct RankingList {
RankingEntry entries[MAX_RANKINGS_ENTRIES];
} RankingList;
typedef struct Rankings {
RankingList lists[RECORDS_WITH_RANKINGS_COUNT * 2];
} Rankings;
typedef struct RankingPlayerInfo {
u32 seed;
u32 recordValue;
String *playerName;
} RankingPlayerInfo;
typedef struct RecordPlayersInfo {
int count;
RankingPlayerInfo players[MAX_RANKINGS_ENTRIES];
} RecordPlayersInfo;
u8 GetRecordsListLength(int listID);
u8 GetRecordsListFirstRecord(int listID);
void sub_0202E858(RankingEntry *entry);
BOOL sub_0202E870(RankingEntry *entry);
int Rankings_SaveSize(void);
void Rankings_Init(Rankings *rankings);
Rankings *SaveData_GetRankings(SaveData *saveData);
void Rankings_RemoveEntry(Rankings *rankings, int listID, u8 entryID);
int RankingsEntries_Size(void);
void *sub_0202E9FC(SaveData *saveData, enum HeapID heapID);
void sub_0202ED0C(SaveData *saveData, int param1, u8 param2, const void **inRankingsEntries, enum HeapID heapID);
RecordPlayersInfo *Rankings_GetCurrentPlayerInfo(SaveData *saveData, int listID, enum HeapID heapID);
RecordPlayersInfo *Rankings_GetConnectedPlayersInfo(Rankings *rankings, int listID, enum HeapID heapID);
void RecordPlayersInfo_Free(RecordPlayersInfo *entry);
#endif // POKEPLATINUM_RANKINGS_H

View File

@ -0,0 +1,8 @@
#ifndef POKEPLATINUM_RANKINGS_MACHINE_H
#define POKEPLATINUM_RANKINGS_MACHINE_H
#include "field_task.h"
void RankingsMachine_InitFieldTask(FieldTask *task, u16 machineID);
#endif // POKEPLATINUM_RANKINGS_MACHINE_H

View File

@ -1,6 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_0202E858_DECL_H
#define POKEPLATINUM_STRUCT_0202E858_DECL_H
typedef struct UnkStruct_0202E858_t UnkStruct_0202E858;
#endif // POKEPLATINUM_STRUCT_0202E858_DECL_H

View File

@ -1,6 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_0202E8C0_DECL_H
#define POKEPLATINUM_STRUCT_0202E8C0_DECL_H
typedef struct UnkStruct_0202E8C0_t UnkStruct_0202E8C0;
#endif // POKEPLATINUM_STRUCT_0202E8C0_DECL_H

View File

@ -1,6 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_0202E91C_DECL_H
#define POKEPLATINUM_STRUCT_0202E91C_DECL_H
typedef struct UnkStruct_0202E91C_t UnkStruct_0202E91C;
#endif // POKEPLATINUM_STRUCT_0202E91C_DECL_H

View File

@ -1,6 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_0202EA80_DECL_H
#define POKEPLATINUM_STRUCT_0202EA80_DECL_H
typedef struct UnkStruct_0202EA80_t UnkStruct_0202EA80;
#endif // POKEPLATINUM_STRUCT_0202EA80_DECL_H

View File

@ -1,10 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_0202E858_H
#define POKEPLATINUM_STRUCT_0202E858_H
typedef struct UnkStruct_0202E858_t {
u32 unk_00;
u32 unk_04;
u16 unk_08[8];
} UnkStruct_0202E858;
#endif // POKEPLATINUM_STRUCT_0202E858_H

View File

@ -1,10 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_0202E8C0_H
#define POKEPLATINUM_STRUCT_0202E8C0_H
#include "struct_defs/struct_0202EA80.h"
typedef struct UnkStruct_0202E8C0_t {
UnkStruct_0202EA80 unk_00[26];
} UnkStruct_0202E8C0;
#endif // POKEPLATINUM_STRUCT_0202E8C0_H

View File

@ -1,10 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_0202E91C_H
#define POKEPLATINUM_STRUCT_0202E91C_H
#include "struct_defs/struct_0202E858.h"
typedef struct UnkStruct_0202E91C_t {
UnkStruct_0202E858 unk_00[13];
} UnkStruct_0202E91C;
#endif // POKEPLATINUM_STRUCT_0202E91C_H

View File

@ -1,10 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_0202EA80_H
#define POKEPLATINUM_STRUCT_0202EA80_H
#include "struct_defs/struct_0202E858.h"
typedef struct UnkStruct_0202EA80_t {
UnkStruct_0202E858 unk_00[6];
} UnkStruct_0202EA80;
#endif // POKEPLATINUM_STRUCT_0202EA80_H

View File

@ -1,11 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_0202EE10_H
#define POKEPLATINUM_STRUCT_0202EE10_H
#include "struct_defs/struct_0202EE10_sub1.h"
typedef struct {
int unk_00;
UnkStruct_0202EE10_sub1 unk_04[6];
} UnkStruct_0202EE10;
#endif // POKEPLATINUM_STRUCT_0202EE10_H

View File

@ -1,12 +0,0 @@
#ifndef POKEPLATINUM_STRUCT_0202EE10_SUB1_H
#define POKEPLATINUM_STRUCT_0202EE10_SUB1_H
#include "string_gf.h"
typedef struct {
u32 unk_00;
u32 unk_04;
String *unk_08;
} UnkStruct_0202EE10_sub1;
#endif // POKEPLATINUM_STRUCT_0202EE10_SUB1_H

View File

@ -1,27 +0,0 @@
#ifndef POKEPLATINUM_UNK_0202E840_H
#define POKEPLATINUM_UNK_0202E840_H
#include "constants/heap.h"
#include "struct_decls/struct_0202E858_decl.h"
#include "struct_decls/struct_0202E8C0_decl.h"
#include "struct_defs/struct_0202EE10.h"
#include "savedata.h"
u8 sub_0202E840(int param0);
u8 sub_0202E84C(int param0);
void sub_0202E858(UnkStruct_0202E858 *param0);
BOOL sub_0202E870(UnkStruct_0202E858 *param0);
int Rankings_SaveSize(void);
void Rankings_Init(UnkStruct_0202E8C0 *param0);
UnkStruct_0202E8C0 *sub_0202E8C0(SaveData *saveData);
void sub_0202E8D4(UnkStruct_0202E8C0 *param0, int param1, u8 param2);
int sub_0202E91C(void);
void *sub_0202E9FC(SaveData *saveData, enum HeapID heapID);
void sub_0202ED0C(SaveData *saveData, int param1, u8 param2, const void **param3, enum HeapID heapID);
UnkStruct_0202EE10 *sub_0202ED8C(SaveData *saveData, int param1, enum HeapID heapID);
UnkStruct_0202EE10 *sub_0202EE10(UnkStruct_0202E8C0 *param0, int param1, enum HeapID heapID);
void sub_0202EE8C(UnkStruct_0202EE10 *param0);
#endif // POKEPLATINUM_UNK_0202E840_H

View File

@ -1,8 +0,0 @@
#ifndef POKEPLATINUM_UNK_0206F314_H
#define POKEPLATINUM_UNK_0206F314_H
#include "field_task.h"
void sub_020703FC(FieldTask *param0, u16 param1);
#endif // POKEPLATINUM_UNK_0206F314_H

View File

@ -137,7 +137,7 @@ Static main
Object main.nef.p/src_mystery_gift.c.o
Object main.nef.p/src_hall_of_fame_entries.c.o
Object main.nef.p/src_unk_0202E2CC.c.o
Object main.nef.p/src_unk_0202E840.c.o
Object main.nef.p/src_rankings.c.o
Object main.nef.p/src_unk_0202EEC0.c.o
Object main.nef.p/src_link_contest_records.c.o
Object main.nef.p/src_unk_0202F180.c.o
@ -273,7 +273,7 @@ Static main
Object main.nef.p/src_unk_0206C660.c.o
Object main.nef.p/src_cutscenes_boat_cutscene_boat_cutscene.c.o
Object main.nef.p/src_tv_episode_segment.c.o
Object main.nef.p/src_unk_0206F314.c.o
Object main.nef.p/src_rankings_machine.c.o
Object main.nef.p/src_unk_02070428.c.o
Object main.nef.p/src_field_move_tasks.c.o
Object main.nef.p/src_unk_020711C8.c.o

View File

@ -14,21 +14,21 @@
JubilifeTV3FGlobalRankingRoom_RecordMachinePokemon:
PlayFanfare SEQ_SE_CONFIRM
LockAll
ScrCmd_1B5 0
StartRankingsMachine 0
ReleaseAll
End
JubilifeTV3FGlobalRankingRoom_RecordMachineBattles:
PlayFanfare SEQ_SE_CONFIRM
LockAll
ScrCmd_1B5 1
StartRankingsMachine 1
ReleaseAll
End
JubilifeTV3FGlobalRankingRoom_RecordMachineContests:
PlayFanfare SEQ_SE_CONFIRM
LockAll
ScrCmd_1B5 2
StartRankingsMachine 2
ReleaseAll
End

View File

@ -13,21 +13,21 @@
JubilifeTV3FGroupRankingRoom_RecordMachinePokemon:
PlayFanfare SEQ_SE_CONFIRM
LockAll
ScrCmd_1B5 3
StartRankingsMachine 3
ReleaseAll
End
JubilifeTV3FGroupRankingRoom_RecordMachineBattles:
PlayFanfare SEQ_SE_CONFIRM
LockAll
ScrCmd_1B5 4
StartRankingsMachine 4
ReleaseAll
End
JubilifeTV3FGroupRankingRoom_RecordMachineContests:
PlayFanfare SEQ_SE_CONFIRM
LockAll
ScrCmd_1B5 5
StartRankingsMachine 5
ReleaseAll
End

View File

@ -2,196 +2,196 @@
"key": 40969,
"messages": [
{
"id": "pl_msg_00000532_00000",
"id": "RankingsMachine_Text_SingleBattlesRecordTitle",
"en_US": "SINGLE BATTLES"
},
{
"id": "pl_msg_00000532_00001",
"id": "RankingsMachine_Text_DoubleBattlesRecordTitle",
"en_US": "DOUBLE BATTLES"
},
{
"id": "pl_msg_00000532_00002",
"id": "RankingsMachine_Text_MultiBattlesRecordTitle",
"en_US": "MULTI BATTLES"
},
{
"id": "pl_msg_00000532_00003",
"id": "RankingsMachine_Text_LinkMultiBattlesRecordTitle",
"en_US": "LINK MULTI BATTLES"
},
{
"id": "pl_msg_00000532_00004",
"id": "RankingsMachine_Text_WiFiBattleRoomRecordTitle",
"en_US": "WI-FI BATTLE ROOM"
},
{
"id": "pl_msg_00000532_00005",
"id": "RankingsMachine_Text_AvgWinStreakRecordTitle",
"en_US": "AVG WIN STREAK"
},
{
"id": "pl_msg_00000532_00006",
"id": "RankingsMachine_Text_PokemonDefeatedRecordTitle",
"en_US": "POKéMON DEFEATED"
},
{
"id": "pl_msg_00000532_00007",
"id": "RankingsMachine_Text_PokemonCaughtRecordTitle",
"en_US": "POKéMON CAUGHT"
},
{
"id": "pl_msg_00000532_00008",
"id": "RankingsMachine_Text_PokemonEggsRecordTitle",
"en_US": "POKéMON EGGS"
},
{
"id": "pl_msg_00000532_00009",
"id": "RankingsMachine_Text_EncounteredWhileFishingRecordTitle",
"en_US": "ENCOUNTERED WHILE FISHING"
},
{
"id": "pl_msg_00000532_00010",
"id": "RankingsMachine_Text_ContestWinsRecordTitle",
"en_US": "CONTEST WINS"
},
{
"id": "pl_msg_00000532_00011",
"id": "RankingsMachine_Text_ContestWinPercentRecordTitle",
"en_US": "CONTEST WIN %"
},
{
"id": "pl_msg_00000532_00012",
"id": "RankingsMachine_Text_RibbonsRecordTitle",
"en_US": "RIBBONS"
},
{
"id": "pl_msg_00000532_00013",
"id": "RankingsMachine_Text_Exit",
"en_US": "EXIT"
},
{
"id": "pl_msg_00000532_00014",
"id": "RankingsMachine_Text_RecordEntryInfo",
"en_US": "{STRVAR_1 50, 0, 0}. {STRVAR_1 3, 1, 0}"
},
{
"id": "pl_msg_00000532_00015",
"id": "RankingsMachine_Text_BattleWinsValue",
"en_US": "{STRVAR_1 53, 0, 0} wins"
},
{
"id": "pl_msg_00000532_00016",
"id": "RankingsMachine_Text_AvgWinStreakValue",
"en_US": "{STRVAR_1 50, 0, 0} wins"
},
{
"id": "pl_msg_00000532_00017",
"id": "RankingsMachine_Text_RibbonsValue",
"en_US": "{STRVAR_1 54, 0, 0}"
},
{
"id": "pl_msg_00000532_00018",
"id": "RankingsMachine_Text_PokemonHatchedValue",
"en_US": "{STRVAR_1 55, 0, 0}"
},
{
"id": "pl_msg_00000532_00019",
"id": "RankingsMachine_Text_PokemonCaughtValue",
"en_US": "{STRVAR_1 55, 0, 0}"
},
{
"id": "pl_msg_00000532_00020",
"id": "RankingsMachine_Text_ContestWinPercentValue",
"en_US": "{STRVAR_1 52, 0, 0}%"
},
{
"id": "pl_msg_00000532_00021",
"id": "RankingsMachine_Text_ContestWinsValue",
"en_US": "{STRVAR_1 53, 0, 0}"
},
{
"id": "pl_msg_00000532_00022",
"id": "RankingsMachine_Text_WhichRecordWouldYouLikeToSee",
"en_US": "Which record would you like to see?"
},
{
"id": "pl_msg_00000532_00023",
"id": "RankingsMachine_Text_SingleBattlesRecordExplanation",
"en_US": [
"The Battle Towers win-streak record\n",
"in Single Battles."
]
},
{
"id": "pl_msg_00000532_00024",
"id": "RankingsMachine_Text_DoubleBattlesRecordExplanation",
"en_US": [
"The Battle Towers win-streak record\n",
"in Double Battles."
]
},
{
"id": "pl_msg_00000532_00025",
"id": "RankingsMachine_Text_MultiBattlesRecordExplanation",
"en_US": [
"The Battle Towers win-streak record\n",
"in Multi Battles."
]
},
{
"id": "pl_msg_00000532_00026",
"id": "RankingsMachine_Text_LinkMultiBattlesRecordExplanation",
"en_US": [
"The Battle Towers win-streak record\n",
"in Link Multi Battles."
]
},
{
"id": "pl_msg_00000532_00027",
"id": "RankingsMachine_Text_WiFiBattlesRecordExplanation",
"en_US": [
"The Battle Towers win-streak record\n",
"in Wi-Fi Battles."
]
},
{
"id": "pl_msg_00000532_00028",
"id": "RankingsMachine_Text_AvgWinStreakRecordExplanation",
"en_US": [
"The average win-streak record\n",
"at the Battle Tower."
]
},
{
"id": "pl_msg_00000532_00029",
"id": "RankingsMachine_Text_PokemonDefeatedRecordExplanation",
"en_US": "The number of Pokémon defeated."
},
{
"id": "pl_msg_00000532_00030",
"id": "RankingsMachine_Text_PokemonCaughtRecordExplanation",
"en_US": [
"The number of Pokémon caught using\n",
"Poké Balls."
]
},
{
"id": "pl_msg_00000532_00031",
"id": "RankingsMachine_Text_PokemonEggsRecordExplanation",
"en_US": [
"The number of Pokémon that were\n",
"hatched from Eggs."
]
},
{
"id": "pl_msg_00000532_00032",
"id": "RankingsMachine_Text_EncounteredWhileFishingRecordExplanation",
"en_US": [
"The number of Pokémon that were\n",
"caught fishing."
]
},
{
"id": "pl_msg_00000532_00033",
"id": "RankingsMachine_Text_ContestWinsRecordExplanation",
"en_US": "The number of Contest wins."
},
{
"id": "pl_msg_00000532_00034",
"id": "RankingsMachine_Text_ContestWinPercentRecordExplanation",
"en_US": "The winning percentage of Contests."
},
{
"id": "pl_msg_00000532_00035",
"id": "RankingsMachine_Text_RibbonsRecordExplanation",
"en_US": [
"The number of Ribbons won in\n",
"Contests."
]
},
{
"id": "pl_msg_00000532_00036",
"id": "RankingsMachine_Text_DeleteRecord",
"en_US": "DEL RECORD"
},
{
"id": "pl_msg_00000532_00037",
"id": "RankingsMachine_Text_SelectTheRecordYouWantToDeleteThenPressA",
"en_US": [
"Select the record you want to\n",
"delete, then press the A Button."
]
},
{
"id": "pl_msg_00000532_00038",
"id": "RankingsMachine_Text_AskDeleteThisRecord",
"en_US": "Delete this record?"
},
{
"id": "pl_msg_00000532_00039",
"id": "RankingsMachine_Text_YourOwnRecordCantBeDeleted",
"en_US": "Your own record cant be deleted."
}
]

View File

@ -102,7 +102,7 @@ static u8 sUsesHighLimit[MAX_RECORDS] = {
[RECORD_POKEMON_EVOLVED] = TRUE,
[RECORD_UNK_013] = TRUE,
[RECORD_UNK_014] = TRUE,
[RECORD_UNK_015] = TRUE,
[RECORD_BATTLE_TOWER_CHALLENGES] = TRUE,
[RECORD_UNK_016] = TRUE,
[RECORD_UNK_017] = TRUE,
[RECORD_UNK_018] = TRUE,
@ -116,7 +116,7 @@ static u8 sUsesHighLimit[MAX_RECORDS] = {
[RECORD_WIFI_BATTLE_WINS] = TRUE,
[RECORD_WIFI_BATTLE_LOSSES] = TRUE,
[RECORD_UNK_028] = TRUE,
[RECORD_UNK_029] = TRUE,
[RECORD_BATTLE_TOWER_VICTORIES] = TRUE,
[RECORD_UNK_030] = TRUE,
[RECORD_UNK_031] = TRUE,
[RECORD_UNK_032] = TRUE,
@ -177,11 +177,11 @@ static u8 sUsesHighLimit[MAX_RECORDS] = {
[RECORD_UNK_087] = FALSE,
[RECORD_UNK_088] = FALSE,
[RECORD_UNK_089] = FALSE,
[RECORD_UNK_090] = FALSE,
[RECORD_UNK_091] = FALSE,
[RECORD_SUPER_CONTEST_PARTICIPATIONS] = FALSE,
[RECORD_LINK_CONTEST_PARTICIPATIONS] = FALSE,
[RECORD_SUPER_CONTEST_WINS] = FALSE,
[RECORD_LINK_CONTEST_WINS] = FALSE,
[RECORD_UNK_094] = TRUE,
[RECORD_RIBBONS_WON] = TRUE,
[RECORD_USED_INEFFECTIVE_MOVE] = FALSE,
[RECORD_FAINTED_ENEMY_MON] = FALSE,
[RECORD_ATTACKED_ALLY] = FALSE,

View File

@ -126,7 +126,7 @@ pokeplatinum_c = files(
'mystery_gift.c',
'hall_of_fame_entries.c',
'unk_0202E2CC.c',
'unk_0202E840.c',
'rankings.c',
'unk_0202EEC0.c',
'link_contest_records.c',
'unk_0202F180.c',
@ -259,7 +259,7 @@ pokeplatinum_c = files(
'unk_0206C660.c',
'cutscenes/boat_cutscene/boat_cutscene.c',
'tv_episode_segment.c',
'unk_0206F314.c',
'rankings_machine.c',
'unk_02070428.c',
'field_move_tasks.c',
'unk_020711C8.c',

View File

@ -800,7 +800,7 @@ BOOL ScrCmd_30F(ScriptContext *param0)
switch (v3) {
case 13:
if (GameRecords_GetRecordValue(v1, RECORD_UNK_029) < 1) {
if (GameRecords_GetRecordValue(v1, RECORD_BATTLE_TOWER_VICTORIES) < 1) {
*v4 = 0;
}

View File

@ -4,7 +4,6 @@
#include <string.h>
#include "struct_decls/struct_0202440C_decl.h"
#include "struct_decls/struct_0202E8C0_decl.h"
#include "struct_defs/dress_up_photo.h"
#include "struct_defs/image_clips.h"
@ -17,12 +16,12 @@
#include "communication_information.h"
#include "communication_system.h"
#include "heap.h"
#include "rankings.h"
#include "record_mixed_rng.h"
#include "savedata.h"
#include "unk_020298BC.h"
#include "unk_0202D05C.h"
#include "unk_0202E2CC.h"
#include "unk_0202E840.h"
#include "unk_02073700.h"
typedef struct {
@ -115,7 +114,7 @@ static void *ov59_021D3088(SaveData *saveData, enum HeapID heapID, u32 param2)
static void ov59_021D3090(const UnkStruct_ov59_021D2FBC *param0)
{
UnkStruct_0202E8C0 *v0 = sub_0202E8C0(param0->saveData);
Rankings *v0 = SaveData_GetRankings(param0->saveData);
sub_0202ED0C(param0->saveData, param0->unk_0C, param0->unk_08, param0->unk_10, param0->heapID);
}
@ -140,7 +139,7 @@ static const UnkStruct_ov59_021D33FC Unk_ov59_021D33FC[] = {
{ (UnkFuncPtr_ov59_021D33FC)ov59_021D2B4C, (UnkFuncPtr_ov59_021D33FC_1)ov59_021D2C70, NULL },
{ (UnkFuncPtr_ov59_021D33FC)ov59_021D2B54, (UnkFuncPtr_ov59_021D33FC_1)ov59_021D2CB4, NULL },
{ (UnkFuncPtr_ov59_021D33FC)ov59_021D2B44, (UnkFuncPtr_ov59_021D33FC_1)ov59_021D2C28, NULL },
{ (UnkFuncPtr_ov59_021D33FC)sub_0202E91C, (UnkFuncPtr_ov59_021D33FC_1)ov59_021D3088, ov59_021D3090 },
{ (UnkFuncPtr_ov59_021D33FC)RankingsEntries_Size, (UnkFuncPtr_ov59_021D33FC_1)ov59_021D3088, ov59_021D3090 },
{ (UnkFuncPtr_ov59_021D33FC)sub_0202D05C, (UnkFuncPtr_ov59_021D33FC_1)ov59_021D30B4, ov59_021D30DC },
{ (UnkFuncPtr_ov59_021D33FC)ov59_021D2B4C, (UnkFuncPtr_ov59_021D33FC_1)ov59_021D2D3C, ov59_021D3028 },
{ (UnkFuncPtr_ov59_021D33FC)ov59_021D2B54, (UnkFuncPtr_ov59_021D33FC_1)ov59_021D2D80, ov59_021D3048 },

438
src/rankings.c Normal file
View File

@ -0,0 +1,438 @@
#include "rankings.h"
#include <nitro.h>
#include <string.h>
#include "generated/game_records.h"
#include "struct_defs/battle_frontier.h"
#include "charcode_util.h"
#include "game_records.h"
#include "heap.h"
#include "record_mixed_rng.h"
#include "save_player.h"
#include "savedata.h"
#include "string_gf.h"
#include "trainer_info.h"
#include "unk_0203061C.h"
#include "res/text/bank/rankings_machine.h"
typedef struct {
int unk_00;
int unk_04;
int unk_08;
RankingEntry *unk_0C[11];
RankingEntry *unk_38[6];
RankingList list;
} UnkStruct_0202EABC;
typedef struct RankingsEntries {
RankingEntry entries[RECORDS_WITH_RANKINGS_COUNT];
} RankingsEntries;
typedef struct RecordListInfo {
u8 length;
u8 firstRecord;
} RecordListInfo;
static const RecordListInfo sRecordsListsInfo[] = {
{ 6, 0 },
{ 4, 6 },
{ 3, 10 }
};
u8 GetRecordsListLength(int listID)
{
return sRecordsListsInfo[listID].length;
}
u8 GetRecordsListFirstRecord(int listID)
{
return sRecordsListsInfo[listID].firstRecord;
}
void RankingEntry_Clear(RankingEntry *entry)
{
entry->seed = 0;
entry->recordValue = 0;
CharCode_FillWithEOS(entry->playerName, TRAINER_NAME_LEN + 1);
SaveData_SetChecksum(SAVE_TABLE_ENTRY_RANKINGS);
}
BOOL RankingEntry_HasPlayerName(RankingEntry *entry)
{
return CharCode_Length(entry->playerName) != 0;
}
int Rankings_SaveSize(void)
{
return sizeof(Rankings);
}
void Rankings_Init(Rankings *rankings)
{
MI_CpuClear8(rankings, sizeof(Rankings));
for (int listID = 0; listID < RECORDS_WITH_RANKINGS_COUNT * 2; listID++) {
for (int entryID = 0; entryID < MAX_RANKINGS_ENTRIES; entryID++) {
RankingEntry_Clear(&(rankings->lists[listID].entries[entryID]));
}
}
SaveData_SetChecksum(SAVE_TABLE_ENTRY_RANKINGS);
}
Rankings *SaveData_GetRankings(SaveData *saveData)
{
SaveData_Checksum(SAVE_TABLE_ENTRY_RANKINGS);
return SaveData_SaveTable(saveData, SAVE_TABLE_ENTRY_RANKINGS);
}
void Rankings_RemoveEntry(Rankings *rankings, int listID, u8 entryID)
{
if (entryID >= MAX_RANKINGS_ENTRIES) {
GF_ASSERT(entryID < MAX_RANKINGS_ENTRIES);
return;
}
RankingList *list = &rankings->lists[listID];
for (int i = entryID; i < MAX_RANKINGS_ENTRIES - 1; i++) {
list->entries[i] = list->entries[i + 1];
}
RankingEntry_Clear(&(list->entries[MAX_RANKINGS_ENTRIES - 1]));
SaveData_SetChecksum(SAVE_TABLE_ENTRY_RANKINGS);
}
int RankingsEntries_Size(void)
{
return sizeof(RankingsEntries);
}
static u32 *GetRecordValues(SaveData *saveData, enum HeapID heapID)
{
int i;
u32 recordValue;
static const int recordIDs[] = {
0,
2,
4,
6,
8,
RECORD_BATTLE_TOWER_VICTORIES,
RECORD_FAINTED_IN_BATTLE,
RECORD_CAUGHT_POKEMON,
RECORD_EGGS_HATCHED,
RECORD_CAUGHT_FISH,
RECORD_SUPER_CONTEST_WINS,
RECORD_SUPER_CONTEST_PARTICIPATIONS,
RECORD_RIBBONS_WON
};
GameRecords *gameRecords = SaveData_GetGameRecords(saveData);
BattleFrontier *frontier = SaveData_GetBattleFrontier(saveData);
u32 *recordValues = Heap_AllocAtEnd(heapID, sizeof(u32) * RECORDS_WITH_RANKINGS_COUNT);
for (i = 0; i < RECORDS_WITH_RANKINGS_COUNT; i++) {
switch (i) {
case 5:
recordValue = GameRecords_GetRecordValue(gameRecords, RECORD_BATTLE_TOWER_CHALLENGES);
if (recordValue > 0) {
recordValue = GameRecords_GetRecordValue(gameRecords, RECORD_BATTLE_TOWER_VICTORIES) / recordValue;
}
recordValues[i] = recordValue;
break;
case 10:
recordValue = GameRecords_GetRecordValue(gameRecords, RECORD_SUPER_CONTEST_WINS);
recordValue += GameRecords_GetRecordValue(gameRecords, RECORD_LINK_CONTEST_WINS);
recordValues[i] = recordValue;
break;
case 11:
recordValue = GameRecords_GetRecordValue(gameRecords, RECORD_SUPER_CONTEST_PARTICIPATIONS);
recordValue += GameRecords_GetRecordValue(gameRecords, RECORD_LINK_CONTEST_PARTICIPATIONS);
if (recordValue > 0) {
recordValue = (recordValues[10] * 100) / recordValue;
}
recordValues[i] = recordValue;
break;
default:
if (i >= 0 && i <= 4) {
recordValues[i] = sub_02030698(frontier, recordIDs[i], 0xFF);
} else {
recordValues[i] = GameRecords_GetRecordValue(gameRecords, recordIDs[i]);
}
}
}
SaveData_SetChecksum(SAVE_TABLE_ENTRY_RANKINGS);
return recordValues;
}
void *sub_0202E9FC(SaveData *saveData, enum HeapID heapID)
{
int i;
u32 seed, unused;
RankingsEntries *rankingsEntries;
String *string;
TrainerInfo *trainerInfo = SaveData_GetTrainerInfo(saveData);
u32 *recordValues;
rankingsEntries = Heap_AllocAtEnd(heapID, sizeof(RankingsEntries));
MI_CpuClear8(rankingsEntries, sizeof(RankingsEntries));
seed = RecordMixedRNG_GetEntrySeed(SaveData_GetRecordMixedRNG(saveData), RECORD_MIXED_RNG_PLAYER_OVERRIDE);
string = TrainerInfo_NameNewString(trainerInfo, heapID);
recordValues = GetRecordValues(saveData, heapID);
for (i = 0; i < RECORDS_WITH_RANKINGS_COUNT; i++) {
unused = 0;
rankingsEntries->entries[i].seed = seed;
String_ToChars(string, rankingsEntries->entries[i].playerName, TRAINER_NAME_LEN + 1);
rankingsEntries->entries[i].recordValue = recordValues[i];
}
Heap_Free(recordValues);
String_Free(string);
SaveData_SetChecksum(SAVE_TABLE_ENTRY_RANKINGS);
return rankingsEntries;
}
static void RankingList_ClearEntries(RankingList *list)
{
for (int i = 0; i < MAX_RANKINGS_ENTRIES; i++) {
RankingEntry_Clear(&list->entries[i]);
}
}
static BOOL CompareEntriesSeedsAndNames(const RankingEntry *entry0, const RankingEntry *entry1)
{
if (entry0->seed != entry1->seed) {
return FALSE;
}
if (CharCode_Compare(entry0->playerName, entry1->playerName)) {
return FALSE;
}
return TRUE;
}
static BOOL sub_0202EABC(UnkStruct_0202EABC *param0, const RankingEntry *entry)
{
for (int i = 0; i < param0->unk_04; i++) {
if (CompareEntriesSeedsAndNames(param0->unk_0C[i], entry)) {
return TRUE;
}
}
return FALSE;
}
static void sub_0202EAEC(Rankings *rankings, UnkStruct_0202EABC *param1, u32 param2, u8 param3, u8 param4, RankingsEntries **rankingsEntries, u8 param6, enum HeapID heapID)
{
int i, v1;
RankingEntry *v2;
RankingList *list;
MI_CpuClear8(param1, sizeof(UnkStruct_0202EABC));
if (param4 == 0) {
list = &(rankings->lists[param3]);
MI_CpuCopy8(list, &(param1->list), sizeof(RankingList));
for (i = 0; i < param6; i++) {
param1->unk_0C[param1->unk_04++] = &(rankingsEntries[i]->entries[param3]);
}
for (i = 0; i < MAX_RANKINGS_ENTRIES; i++) {
if (!RankingEntry_HasPlayerName(&(param1->list.entries[i]))) {
continue;
}
if (sub_0202EABC(param1, &(param1->list.entries[i]))) {
continue;
}
param1->unk_38[param1->unk_00++] = &(param1->list.entries[i]);
}
} else {
list = &(rankings->lists[param3 + RECORDS_WITH_RANKINGS_COUNT]);
MI_CpuCopy8(list, &(param1->list), sizeof(RankingList));
for (i = 0; i < param6; i++) {
if ((rankingsEntries[i]->entries[param3].seed == 0) || (rankingsEntries[i]->entries[param3].seed != param2)) {
continue;
}
param1->unk_0C[param1->unk_04++] = &(rankingsEntries[i]->entries[param3]);
}
for (i = 0; i < MAX_RANKINGS_ENTRIES; i++) {
if (!RankingEntry_HasPlayerName(&(param1->list.entries[i]))) {
continue;
}
if (param1->list.entries[i].seed != param2) {
continue;
}
if (sub_0202EABC(param1, &(param1->list.entries[i]))) {
continue;
}
param1->unk_38[param1->unk_00++] = &(param1->list.entries[i]);
}
}
param1->unk_08 = param1->unk_04 + param1->unk_00;
for (i = 0; i < param1->unk_00; i++) {
param1->unk_0C[i + param1->unk_04] = param1->unk_38[i];
}
for (i = 0; i < (param1->unk_08 - 1); i++) {
for (v1 = (param1->unk_08 - 1); v1 > i; v1--) {
if (param1->unk_0C[i]->recordValue >= param1->unk_0C[v1]->recordValue) {
continue;
}
v2 = param1->unk_0C[i];
param1->unk_0C[i] = param1->unk_0C[v1];
param1->unk_0C[v1] = v2;
}
}
RankingList_ClearEntries(list);
for (i = 0; (i < MAX_RANKINGS_ENTRIES && i < param1->unk_08); i++) {
list->entries[i] = *(param1->unk_0C[i]);
}
}
static void sub_0202ECB0(Rankings *rankings, u32 param1, u8 param2, RankingsEntries **rankingsEntries, u8 param4, enum HeapID heapID)
{
UnkStruct_0202EABC *v2 = Heap_AllocAtEnd(heapID, sizeof(UnkStruct_0202EABC));
sub_0202EAEC(rankings, v2, param1, param2, 0, rankingsEntries, param4, heapID);
if (param1 != 0) {
sub_0202EAEC(rankings, v2, param1, param2, 1, rankingsEntries, param4, heapID);
}
Heap_Free(v2);
}
void sub_0202ED0C(SaveData *saveData, int param1, u8 param2, const void **inRankingsEntries, enum HeapID heapID)
{
u8 i, v1;
u32 v2;
RankingsEntries *rankingsEntries[5];
Rankings *rankings = SaveData_GetRankings(saveData);
v2 = RecordMixedRNG_GetEntrySeed(SaveData_GetRecordMixedRNG(saveData), RECORD_MIXED_RNG_PLAYER_OVERRIDE);
v1 = 0;
for (i = 0; i < param2; i++) {
if (i == param1) {
continue;
}
if (inRankingsEntries[i] == NULL) {
continue;
}
rankingsEntries[v1++] = (RankingsEntries *)inRankingsEntries[i];
}
if (v1 == 0) {
return;
}
for (i = 0; i < 13; i++) {
sub_0202ECB0(rankings, v2, i, rankingsEntries, v1, heapID);
}
SaveData_SetChecksum(SAVE_TABLE_ENTRY_RANKINGS);
return;
}
RecordPlayersInfo *Rankings_GetCurrentPlayerInfo(SaveData *saveData, int listID, enum HeapID heapID)
{
int i, firstRecordID;
u32 seed;
RecordPlayersInfo *playersInfo;
u32 *recordValues;
TrainerInfo *trainerInfo = SaveData_GetTrainerInfo(saveData);
playersInfo = Heap_Alloc(heapID, sizeof(RecordPlayersInfo));
MI_CpuClear8(playersInfo, sizeof(RecordPlayersInfo));
seed = RecordMixedRNG_GetEntrySeed(SaveData_GetRecordMixedRNG(saveData), RECORD_MIXED_RNG_PLAYER_OVERRIDE);
recordValues = GetRecordValues(saveData, heapID);
playersInfo->count = GetRecordsListLength(listID);
firstRecordID = GetRecordsListFirstRecord(listID);
for (i = 0; i < playersInfo->count; i++) {
playersInfo->players[i].seed = seed;
playersInfo->players[i].recordValue = recordValues[i + firstRecordID];
playersInfo->players[i].playerName = TrainerInfo_NameNewString(trainerInfo, heapID);
}
Heap_Free(recordValues);
return playersInfo;
}
RecordPlayersInfo *Rankings_GetConnectedPlayersInfo(Rankings *rankings, int listID, enum HeapID heapID)
{
int i;
RecordPlayersInfo *playersInfo = Heap_Alloc(heapID, sizeof(RecordPlayersInfo));
RankingList *list;
MI_CpuClear8(playersInfo, sizeof(RecordPlayersInfo));
list = &rankings->lists[listID];
for (i = 0; i < MAX_RANKINGS_ENTRIES; i++) {
if (!RankingEntry_HasPlayerName(&list->entries[i])) {
continue;
}
playersInfo->players[playersInfo->count].seed = list->entries[i].seed;
playersInfo->players[playersInfo->count].recordValue = list->entries[i].recordValue;
playersInfo->players[playersInfo->count].playerName = String_Init(TRAINER_NAME_LEN + 1, heapID);
String_CopyChars(playersInfo->players[playersInfo->count].playerName, list->entries[i].playerName);
++playersInfo->count;
}
return playersInfo;
}
void RecordPlayersInfo_Free(RecordPlayersInfo *playersInfo)
{
int i;
for (i = 0; i < MAX_RANKINGS_ENTRIES; i++) {
if (playersInfo->players[i].playerName != NULL) {
String_Free(playersInfo->players[i].playerName);
}
}
MI_CpuClear8(playersInfo, sizeof(RecordPlayersInfo));
Heap_Free(playersInfo);
playersInfo = NULL;
SaveData_SetChecksum(SAVE_TABLE_ENTRY_RANKINGS);
}

995
src/rankings_machine.c Normal file
View File

@ -0,0 +1,995 @@
#include "rankings_machine.h"
#include <nitro.h>
#include <string.h>
#include "constants/field_base_tiles.h"
#include "constants/scrcmd.h"
#include "field/field_system.h"
#include "overlay005/sprite_resource_manager.h"
#include "bg_window.h"
#include "field_task.h"
#include "font.h"
#include "game_options.h"
#include "heap.h"
#include "list_menu.h"
#include "menu.h"
#include "message.h"
#include "narc.h"
#include "rankings.h"
#include "render_window.h"
#include "save_player.h"
#include "savedata.h"
#include "sound_playback.h"
#include "sprite.h"
#include "sprite_system.h"
#include "string_gf.h"
#include "string_list.h"
#include "string_template.h"
#include "system.h"
#include "text.h"
#include "res/text/bank/rankings_machine.h"
#define PLAYERID_OWN 0xFF
#define VALUE_STRINGS_COUNT 7
#define MAX_RECORDS_PER_MACHINE 6
#define DELETE_INSTRUCTIONS_STRINGS_COUNT 3
#define MANAGED_SPRITE_CURSOR 0
#define MANAGED_SPRITE_DELETE_WINDOW 1
#define RANKINGS_WINDOW_WIDTH 8
#define RANKINGS_WINDOW_HEIGHT 2
#define BASE_TILE_RANKINGS_WINDOW (BASE_TILE_STANDARD_WINDOW_FRAME - MESSAGE_WINDOW_TILE_COUNT - YES_NO_MENU_TILE_COUNT - RANKINGS_WINDOW_WIDTH * RANKINGS_WINDOW_HEIGHT)
typedef struct RankingsMachineText {
MessageLoader *msgLoader;
StringTemplate *strTemplate;
String *strBuffer;
String *exit;
String *whichRecord;
String *deleteRecord;
String *recordEntryInfo;
String *values[VALUE_STRINGS_COUNT];
String *titles[MAX_RECORDS_PER_MACHINE];
String *explanations[MAX_RECORDS_PER_MACHINE];
String *deleteInstructions[DELETE_INSTRUCTIONS_STRINGS_COUNT];
} RankingsMachineText;
typedef struct MachineRankingInfo {
RankingPlayerInfo *playerInfo;
u16 exists;
u8 playerID;
} MachineRankingInfo;
typedef struct MachineRankings {
int rankingsCount;
MachineRankingInfo rankingsInfo[7];
} MachineRankings;
typedef struct RecordPrintingData {
u32 maxScore;
u16 maxDigits;
u16 valueString;
} RecordPrintingData;
typedef struct RankingsMachineManager {
enum HeapID heapID;
int *unused_04;
int unused_08;
int deleteState;
u16 bgMain0Priority;
u16 bgMain1Priority;
u16 unused_14;
u8 listID;
u8 mode;
u8 recordsCount;
u8 firstRecord;
u16 textDelay;
u16 frame;
u8 printerID;
u8 selectedRecordID;
u8 unused_20;
u8 lastRankingID;
u16 startListPos;
u16 startCursorPos;
u16 unused_26;
u16 cursorPos;
RankingsMachineText text;
ListMenuTemplate listMenuTemplate;
ListMenu *listMenu;
StringList *stringList;
Menu *menu;
FieldSystem *fieldSystem;
BgConfig *bgConfig;
Window listWindow;
Window msgBoxWindow;
Window rankingsWindow;
Window unused_104[3];
SpriteResourceManager spriteManager;
ManagedSprite *managedSprites[2];
Rankings *rankings;
RecordPlayersInfo *recordsPlayersInfo[MAX_RECORDS_PER_MACHINE + 1];
MachineRankings *machineRankings;
MachineRankingInfo *rankingToDelete;
u8 rankingIDs[MAX_RANKINGS_ENTRIES];
} RankingsMachineManager;
typedef struct RankingsMachine {
int state;
u16 id;
RankingsMachineManager *manager;
} RankingsMachine;
static void RankingsMachine_NewRankings(RankingsMachineManager *machineMan, SaveData *saveData);
static void RankingsMachine_FreeRankings(RankingsMachineManager *machineMan);
static void RankingsMachine_InitStrings(RankingsMachineManager *machineMan);
static void RankingsMachine_FreeStrings(RankingsMachineManager *machineMan);
static void RankingsMachine_InitBg(RankingsMachineManager *machineMan);
static void RankingsMachine_FreeBg(RankingsMachineManager *machineMan);
static void RankingsMachine_InitSprites(RankingsMachineManager *machineMan);
static void RankingsMachine_FreeSprites(RankingsMachineManager *machineMan);
static void RankingsMachine_ShowRecordsList(RankingsMachineManager *machineMan, u16 startListPos, u16 startCursorPos);
static void RankingsMachine_RemoveRecordsList(RankingsMachineManager *machineMan);
static void RankingsMachine_SetCursorPos(ListMenu *listMenu, u32 unused, u8 mute);
static void RankingsMachine_PrintDeleteInstruction(RankingsMachineManager *machineMan);
static void RankingsMachine_PrepareForDeletingRecord(RankingsMachineManager *machineMan);
static void RankingsMachine_PrintRecordExplanation(RankingsMachineManager *machineMan);
static void RankingsMachine_PrintRecordRankings(RankingsMachineManager *machineMan, BOOL showDeleteScreen);
static void RankingsMachine_ShowRankingList(RankingsMachineManager *machineMan, u16 cursorPos);
static void RankingsMachine_RemoveRankingList(RankingsMachineManager *machineMan);
enum RankingsMachineState {
STATE_INIT_MANAGER,
STATE_INIT,
STATE_PRINT_RECORD_TITLES,
STATE_HANDLE_RECORDS_LIST_INPUT,
STATE_SHOW_RANKINGS_LIST,
STATE_HANDLE_RANKINGS_LIST_INPUT,
STATE_HANDLE_DELETE_RANKINGS_INPUT,
STATE_ASK_DELETE_RANKING,
STATE_CANT_DELETE_OWN_RANKING,
STATE_UNUSED,
STATE_FREE,
STATE_FREE_MANAGER,
STATE_FREE_MACHINE,
};
static const ListMenuTemplate sRankingsMachineListMenuTemplate = {
.choices = NULL,
.cursorCallback = NULL,
.printCallback = NULL,
.window = NULL,
.count = 0,
.maxDisplay = 7,
.headerXOffset = 2,
.textXOffset = 8,
.cursorXOffset = 1,
.yOffset = 0,
.textColorFg = 1,
.textColorBg = 15,
.textColorShadow = 2,
.letterSpacing = 0,
.lineSpacing = 0,
.pagerMode = PAGER_MODE_LEFT_RIGHT_PAD,
.fontID = FONT_SYSTEM,
.cursorType = 1,
.parent = NULL
};
static const RecordPrintingData sPrintingDataBattleRecords[] = {
{
.maxScore = 9999,
.maxDigits = 4,
.valueString = RankingsMachine_Text_BattleWinsValue,
},
{
.maxScore = 9999,
.maxDigits = 4,
.valueString = RankingsMachine_Text_BattleWinsValue,
},
{
.maxScore = 9999,
.maxDigits = 4,
.valueString = RankingsMachine_Text_BattleWinsValue,
},
{
.maxScore = 9999,
.maxDigits = 4,
.valueString = RankingsMachine_Text_BattleWinsValue,
},
{
.maxScore = 9999,
.maxDigits = 4,
.valueString = RankingsMachine_Text_BattleWinsValue,
},
{
.maxScore = 7,
.maxDigits = 1,
.valueString = RankingsMachine_Text_AvgWinStreakValue,
},
};
static const RecordPrintingData sPrintingDataPokemonRecords[] = {
{
.maxScore = 999999,
.maxDigits = 6,
.valueString = RankingsMachine_Text_PokemonCaughtValue,
},
{
.maxScore = 999999,
.maxDigits = 6,
.valueString = RankingsMachine_Text_PokemonCaughtValue,
},
{
.maxScore = 999999,
.maxDigits = 6,
.valueString = RankingsMachine_Text_PokemonHatchedValue,
},
{
.maxScore = 999999,
.maxDigits = 6,
.valueString = RankingsMachine_Text_PokemonCaughtValue,
},
};
static const RecordPrintingData sPrintingDataContestRecords[] = {
{
.maxScore = 9999,
.maxDigits = 4,
.valueString = RankingsMachine_Text_ContestWinsValue,
},
{
.maxScore = 100,
.maxDigits = 4,
.valueString = RankingsMachine_Text_ContestWinPercentValue,
},
{
.maxScore = 65535,
.maxDigits = 5,
.valueString = RankingsMachine_Text_RibbonsValue,
},
};
static const RecordPrintingData *const sRecordsPrintingData[] = {
sPrintingDataBattleRecords,
sPrintingDataPokemonRecords,
sPrintingDataContestRecords
};
static int RankingsMachine_InitManager(RankingsMachine *rankingsMachine, FieldSystem *fieldSystem, u16 machineID)
{
RankingsMachineManager *machineMan;
SaveData *saveData = fieldSystem->saveData;
Heap_Create(HEAP_ID_APPLICATION, HEAP_ID_RANKINGS_MACHINE, HEAP_SIZE_RECORD_LIST);
machineMan = Heap_Alloc(HEAP_ID_RANKINGS_MACHINE, sizeof(RankingsMachineManager));
MI_CpuClear8(machineMan, sizeof(RankingsMachineManager));
machineMan->heapID = HEAP_ID_RANKINGS_MACHINE;
machineMan->listID = machineID % 3;
machineMan->mode = machineID / 3;
machineMan->recordsCount = GetRecordsListLength(machineMan->listID);
machineMan->firstRecord = GetRecordsListFirstRecord(machineMan->listID);
machineMan->fieldSystem = fieldSystem;
machineMan->bgConfig = fieldSystem->bgConfig;
machineMan->rankings = SaveData_GetRankings(saveData);
machineMan->textDelay = Options_TextFrameDelay(SaveData_GetOptions(saveData));
machineMan->frame = Options_Frame(SaveData_GetOptions(saveData));
rankingsMachine->manager = machineMan;
return STATE_INIT;
}
static int RankingsMachine_FreeManager(RankingsMachine *rankingsMachine)
{
int recordID, rankingID, entryIDOffset, heapID;
MachineRankingInfo *rankingInfo;
RankingsMachineManager *machineMan = rankingsMachine->manager;
for (recordID = 0; recordID < machineMan->recordsCount; recordID++) {
entryIDOffset = 0;
for (rankingID = 0; rankingID < machineMan->machineRankings[recordID].rankingsCount; rankingID++) {
rankingInfo = &(machineMan->machineRankings[recordID].rankingsInfo[rankingID]);
if (rankingInfo->playerID == PLAYERID_OWN || rankingInfo->exists) {
continue;
}
Rankings_RemoveEntry(machineMan->rankings, (machineMan->mode * 13) + machineMan->firstRecord + recordID, rankingInfo->playerID - entryIDOffset);
++entryIDOffset;
}
}
heapID = machineMan->heapID;
Heap_Free(machineMan);
MI_CpuClear8(machineMan, sizeof(RankingsMachineManager));
Heap_Destroy(heapID);
return STATE_FREE_MACHINE;
}
static int RankingsMachine_Init(RankingsMachineManager *machineMan, SaveData *saveData)
{
RankingsMachine_NewRankings(machineMan, saveData);
RankingsMachine_InitStrings(machineMan);
RankingsMachine_InitBg(machineMan);
RankingsMachine_InitSprites(machineMan);
return STATE_PRINT_RECORD_TITLES;
}
static int RankingsMachine_Free(RankingsMachineManager *machineMan)
{
RankingsMachine_FreeSprites(machineMan);
RankingsMachine_FreeBg(machineMan);
RankingsMachine_FreeStrings(machineMan);
RankingsMachine_FreeRankings(machineMan);
return STATE_FREE_MANAGER;
}
static int RankingsMachine_StateShowRecordsList(RankingsMachineManager *machineMan)
{
RankingsMachine_ShowRecordsList(machineMan, machineMan->startListPos, machineMan->startCursorPos);
return STATE_HANDLE_RECORDS_LIST_INPUT;
}
static int RankingsMachine_HandleRecordsListInput(RankingsMachineManager *machineMan)
{
s32 input = ListMenu_ProcessInput(machineMan->listMenu);
if (JOY_NEW(PAD_BUTTON_B)) {
Sound_PlayEffect(SEQ_SE_CONFIRM);
RankingsMachine_RemoveRecordsList(machineMan);
return STATE_FREE;
}
if (!(JOY_NEW(PAD_BUTTON_A))) {
return STATE_HANDLE_RECORDS_LIST_INPUT;
}
Sound_PlayEffect(SEQ_SE_CONFIRM);
switch (input) {
case MENU_NOTHING_CHOSEN:
case MENU_CANCEL:
case 0xFFFF:
RankingsMachine_RemoveRecordsList(machineMan);
return STATE_FREE;
default:
machineMan->selectedRecordID = input;
machineMan->cursorPos = 0;
RankingsMachine_RemoveRecordsList(machineMan);
return STATE_SHOW_RANKINGS_LIST;
}
return STATE_HANDLE_RECORDS_LIST_INPUT;
}
static int RankingsMachine_StateShowRankingList(RankingsMachineManager *machineMan)
{
RankingsMachine_ShowRankingList(machineMan, machineMan->cursorPos);
return STATE_HANDLE_RANKINGS_LIST_INPUT;
}
static int RankingsMachine_HandleRankingListInput(RankingsMachineManager *machineMan)
{
if (JOY_NEW(PAD_BUTTON_B | PAD_BUTTON_A)) {
Sound_PlayEffect(SEQ_SE_CONFIRM);
RankingsMachine_RemoveRankingList(machineMan);
return STATE_PRINT_RECORD_TITLES;
}
if (JOY_NEW(PAD_BUTTON_SELECT)) {
Sound_PlayEffect(SEQ_SE_CONFIRM);
RankingsMachine_PrepareForDeletingRecord(machineMan);
return STATE_HANDLE_DELETE_RANKINGS_INPUT;
}
return STATE_HANDLE_RANKINGS_LIST_INPUT;
}
static int RankingsMachine_HandleDeleteRankingInput(RankingsMachineManager *machineMan)
{
if (JOY_NEW(PAD_BUTTON_B)) {
Sound_PlayEffect(SEQ_SE_CONFIRM);
RankingsMachine_PrintRecordExplanation(machineMan);
return STATE_HANDLE_RANKINGS_LIST_INPUT;
}
if (JOY_NEW(PAD_BUTTON_A)) {
Sound_PlayEffect(SEQ_SE_CONFIRM);
machineMan->deleteState = 0;
machineMan->rankingToDelete = &(machineMan->machineRankings[machineMan->selectedRecordID].rankingsInfo[machineMan->rankingIDs[machineMan->cursorPos]]);
if (machineMan->rankingToDelete->playerID == PLAYERID_OWN) {
return STATE_CANT_DELETE_OWN_RANKING;
}
return STATE_ASK_DELETE_RANKING;
}
if (JOY_NEW(PAD_KEY_UP)) {
if (machineMan->cursorPos > 0) {
Sound_PlayEffect(SEQ_SE_CONFIRM);
--machineMan->cursorPos;
ManagedSprite_SetPositionXY(machineMan->managedSprites[MANAGED_SPRITE_CURSOR], 126, 16 + 16 * machineMan->cursorPos);
}
}
if (JOY_NEW(PAD_KEY_DOWN)) {
if (machineMan->cursorPos < machineMan->lastRankingID - 1) {
Sound_PlayEffect(SEQ_SE_CONFIRM);
++machineMan->cursorPos;
ManagedSprite_SetPositionXY(machineMan->managedSprites[MANAGED_SPRITE_CURSOR], 126, 16 + 16 * machineMan->cursorPos);
}
}
return STATE_HANDLE_DELETE_RANKINGS_INPUT;
}
static void RankingsMachine_MakeYesNoMenu(RankingsMachineManager *machineMan)
{
static const WindowTemplate yesNoWindowTemplate = {
.bgLayer = BG_LAYER_MAIN_3,
.tilemapLeft = 25,
.tilemapTop = 13,
.width = 6,
.height = 4,
.palette = PLTT_13,
.baseTile = 0x355,
};
machineMan->menu = Menu_MakeYesNoChoice(machineMan->bgConfig, &yesNoWindowTemplate, BASE_TILE_STANDARD_WINDOW_FRAME, 11, machineMan->heapID);
}
static int RankingsMachine_AskDeleteRanking(RankingsMachineManager *machineMan)
{
switch (machineMan->deleteState) {
case 0:
Window_FillTilemap(&machineMan->msgBoxWindow, PIXEL_FILL(15));
machineMan->printerID = Text_AddPrinterWithParamsAndColor(&machineMan->msgBoxWindow, FONT_MESSAGE, machineMan->text.deleteInstructions[1], 0, 0, machineMan->textDelay, TEXT_COLOR(1, 2, 15), NULL);
ManagedSprite_SetExplicitPalette(machineMan->managedSprites[MANAGED_SPRITE_CURSOR], 2);
machineMan->deleteState++;
break;
case 1:
if (Text_IsPrinterActive(machineMan->printerID)) {
break;
}
RankingsMachine_MakeYesNoMenu(machineMan);
machineMan->deleteState++;
break;
case 2:
switch (Menu_ProcessInputAndHandleExit(machineMan->menu, machineMan->heapID)) {
case MENU_YES:
machineMan->deleteState++;
break;
case MENU_CANCEL:
machineMan->deleteState = 0xFF;
break;
}
break;
case 3:
machineMan->rankingToDelete->exists = FALSE;
RankingsMachine_PrintRecordRankings(machineMan, TRUE);
ManagedSprite_SetExplicitPalette(machineMan->managedSprites[MANAGED_SPRITE_CURSOR], 1);
machineMan->deleteState = 0;
return STATE_HANDLE_DELETE_RANKINGS_INPUT;
case 0xFF:
RankingsMachine_PrintDeleteInstruction(machineMan);
ManagedSprite_SetExplicitPalette(machineMan->managedSprites[MANAGED_SPRITE_CURSOR], 1);
machineMan->deleteState = 0;
return STATE_HANDLE_DELETE_RANKINGS_INPUT;
}
return STATE_ASK_DELETE_RANKING;
}
static int RankingsMachine_CantDeleteOwnRanking(RankingsMachineManager *machineMan)
{
switch (machineMan->deleteState) {
case 0:
Sound_PlayEffect(SEQ_SE_DP_CUSTOM06);
Window_FillTilemap(&machineMan->msgBoxWindow, PIXEL_FILL(15));
machineMan->printerID = Text_AddPrinterWithParamsAndColor(&machineMan->msgBoxWindow, FONT_MESSAGE, machineMan->text.deleteInstructions[2], 0, 0, machineMan->textDelay, TEXT_COLOR(1, 2, 15), NULL);
ManagedSprite_SetExplicitPalette(machineMan->managedSprites[MANAGED_SPRITE_CURSOR], 2);
machineMan->deleteState++;
break;
case 1:
if (Text_IsPrinterActive(machineMan->printerID)) {
break;
}
machineMan->deleteState++;
break;
case 2:
if (!(JOY_NEW(PAD_BUTTON_A | PAD_BUTTON_B))) {
break;
}
Sound_PlayEffect(SEQ_SE_CONFIRM);
RankingsMachine_PrintDeleteInstruction(machineMan);
ManagedSprite_SetExplicitPalette(machineMan->managedSprites[MANAGED_SPRITE_CURSOR], 1);
machineMan->deleteState = 0;
return STATE_HANDLE_DELETE_RANKINGS_INPUT;
}
return STATE_CANT_DELETE_OWN_RANKING;
}
static void RankingsMachine_NewRankings(RankingsMachineManager *machineMan, SaveData *saveData)
{
int recordID, playerID, rankingID, addedOwnPlayerID;
RecordPlayersInfo *playersInfo;
machineMan->machineRankings = Heap_Alloc(machineMan->heapID, sizeof(MachineRankings) * machineMan->recordsCount);
MI_CpuClear8(machineMan->machineRankings, sizeof(MachineRankings) * machineMan->recordsCount);
machineMan->recordsPlayersInfo[0] = Rankings_GetCurrentPlayerInfo(saveData, machineMan->listID, machineMan->heapID);
for (recordID = 0; recordID < machineMan->recordsCount; recordID++) {
machineMan->recordsPlayersInfo[recordID + 1] = Rankings_GetConnectedPlayersInfo(machineMan->rankings, (machineMan->mode * 13) + machineMan->firstRecord + recordID, machineMan->heapID);
playersInfo = machineMan->recordsPlayersInfo[recordID + 1];
rankingID = 0;
addedOwnPlayerID = FALSE;
if (playersInfo->count == 0) {
machineMan->machineRankings[recordID].rankingsInfo[0].playerInfo = &(machineMan->recordsPlayersInfo[0]->players[recordID]);
machineMan->machineRankings[recordID].rankingsInfo[0].exists = TRUE;
machineMan->machineRankings[recordID].rankingsInfo[0].playerID = PLAYERID_OWN;
machineMan->machineRankings[recordID].rankingsCount = 1;
} else {
for (playerID = 0; playerID < playersInfo->count; playerID++) {
if (addedOwnPlayerID == FALSE && machineMan->recordsPlayersInfo[0]->players[recordID].recordValue >= playersInfo->players[playerID].recordValue) {
machineMan->machineRankings[recordID].rankingsInfo[rankingID].playerInfo = &(machineMan->recordsPlayersInfo[0]->players[recordID]);
machineMan->machineRankings[recordID].rankingsInfo[rankingID].exists = TRUE;
machineMan->machineRankings[recordID].rankingsInfo[rankingID].playerID = PLAYERID_OWN;
++rankingID;
machineMan->machineRankings[recordID].rankingsInfo[rankingID].playerInfo = &(playersInfo->players[playerID]);
machineMan->machineRankings[recordID].rankingsInfo[rankingID].exists = TRUE;
machineMan->machineRankings[recordID].rankingsInfo[rankingID].playerID = playerID;
addedOwnPlayerID = TRUE;
} else {
machineMan->machineRankings[recordID].rankingsInfo[rankingID].playerInfo = &(playersInfo->players[playerID]);
machineMan->machineRankings[recordID].rankingsInfo[rankingID].exists = TRUE;
machineMan->machineRankings[recordID].rankingsInfo[rankingID].playerID = playerID;
}
++rankingID;
}
if (!addedOwnPlayerID) {
machineMan->machineRankings[recordID].rankingsInfo[rankingID].playerInfo = &(machineMan->recordsPlayersInfo[0]->players[recordID]);
machineMan->machineRankings[recordID].rankingsInfo[rankingID].exists = TRUE;
machineMan->machineRankings[recordID].rankingsInfo[rankingID].playerID = PLAYERID_OWN;
}
machineMan->machineRankings[recordID].rankingsCount = playersInfo->count + 1;
}
}
}
static void RankingsMachine_FreeRankings(RankingsMachineManager *machineMan)
{
int i;
for (i = 0; i < machineMan->recordsCount + 1; i++) {
RecordPlayersInfo_Free(machineMan->recordsPlayersInfo[i]);
}
Heap_Free(machineMan->machineRankings);
}
static void RankingsMachine_InitStrings(RankingsMachineManager *machineMan)
{
int i;
machineMan->text.msgLoader = MessageLoader_Init(MSG_LOADER_PRELOAD_ENTIRE_BANK, NARC_INDEX_MSGDATA__PL_MSG, TEXT_BANK_RANKINGS_MACHINE, machineMan->heapID);
machineMan->text.strTemplate = StringTemplate_New(2, (38 * 2), machineMan->heapID);
machineMan->text.strBuffer = String_Init((38 * 2), machineMan->heapID);
machineMan->text.exit = MessageLoader_GetNewString(machineMan->text.msgLoader, RankingsMachine_Text_Exit);
machineMan->text.whichRecord = MessageLoader_GetNewString(machineMan->text.msgLoader, RankingsMachine_Text_WhichRecordWouldYouLikeToSee);
machineMan->text.deleteRecord = MessageLoader_GetNewString(machineMan->text.msgLoader, RankingsMachine_Text_DeleteRecord);
machineMan->text.recordEntryInfo = MessageLoader_GetNewString(machineMan->text.msgLoader, RankingsMachine_Text_RecordEntryInfo);
for (i = 0; i < machineMan->recordsCount; i++) {
machineMan->text.titles[i] = MessageLoader_GetNewString(machineMan->text.msgLoader, RankingsMachine_Text_SingleBattlesRecordTitle + machineMan->firstRecord + i);
machineMan->text.explanations[i] = MessageLoader_GetNewString(machineMan->text.msgLoader, RankingsMachine_Text_SingleBattlesRecordExplanation + machineMan->firstRecord + i);
}
for (i = 0; i < VALUE_STRINGS_COUNT; i++) {
machineMan->text.values[i] = MessageLoader_GetNewString(machineMan->text.msgLoader, RankingsMachine_Text_BattleWinsValue + i);
}
for (i = 0; i < DELETE_INSTRUCTIONS_STRINGS_COUNT; i++) {
machineMan->text.deleteInstructions[i] = MessageLoader_GetNewString(machineMan->text.msgLoader, RankingsMachine_Text_SelectTheRecordYouWantToDeleteThenPressA + i);
}
}
static void RankingsMachine_FreeStrings(RankingsMachineManager *machineMan)
{
int i;
for (i = 0; i < DELETE_INSTRUCTIONS_STRINGS_COUNT; i++) {
String_Free(machineMan->text.deleteInstructions[i]);
}
for (i = 0; i < VALUE_STRINGS_COUNT; i++) {
String_Free(machineMan->text.values[i]);
}
for (i = 0; i < machineMan->recordsCount; i++) {
String_Free(machineMan->text.titles[i]);
String_Free(machineMan->text.explanations[i]);
}
String_Free(machineMan->text.recordEntryInfo);
String_Free(machineMan->text.deleteRecord);
String_Free(machineMan->text.whichRecord);
String_Free(machineMan->text.exit);
String_Free(machineMan->text.strBuffer);
StringTemplate_Free(machineMan->text.strTemplate);
MessageLoader_Free(machineMan->text.msgLoader);
}
static void RankingsMachine_InitBg(RankingsMachineManager *machineMan)
{
Bg_ClearTilesRange(BG_LAYER_MAIN_1, 32 * (24 * (12 + 2) + 9 + 1), 0, machineMan->heapID);
Bg_FillTilemapRect(machineMan->bgConfig, BG_LAYER_MAIN_1, 0, 0, 0, 32, 32, 17);
Bg_ScheduleTilemapTransfer(machineMan->bgConfig, BG_LAYER_MAIN_1);
Bg_ToggleLayer(BG_LAYER_MAIN_1, 1);
machineMan->bgMain0Priority = Bg_GetPriority(machineMan->bgConfig, BG_LAYER_MAIN_0);
machineMan->bgMain1Priority = Bg_GetPriority(machineMan->bgConfig, BG_LAYER_MAIN_1);
Bg_SetPriority(BG_LAYER_MAIN_0, 2);
Bg_SetPriority(BG_LAYER_MAIN_1, 1);
LoadMessageBoxGraphics(machineMan->bgConfig, BG_LAYER_MAIN_3, BASE_TILE_SCROLLING_MESSAGE_BOX, 10, machineMan->frame, machineMan->heapID);
LoadStandardWindowGraphics(machineMan->bgConfig, BG_LAYER_MAIN_3, BASE_TILE_STANDARD_WINDOW_FRAME, 11, 0, machineMan->heapID);
LoadStandardWindowGraphics(machineMan->bgConfig, BG_LAYER_MAIN_1, BASE_TILE_STANDARD_WINDOW_FRAME, 11, 0, machineMan->heapID);
Font_LoadTextPalette(0, 13 * PALETTE_SIZE_BYTES, machineMan->heapID);
Font_LoadScreenIndicatorsPalette(0, 12 * PALETTE_SIZE_BYTES, machineMan->heapID);
Window_Add(machineMan->bgConfig, &machineMan->msgBoxWindow, BG_LAYER_MAIN_3, 2, 19, 27, 4, 12, BASE_TILE_STANDARD_WINDOW_FRAME - MESSAGE_WINDOW_TILE_COUNT);
Window_FillTilemap(&machineMan->msgBoxWindow, PIXEL_FILL(15));
}
static void RankingsMachine_FreeBg(RankingsMachineManager *machineMan)
{
Window_EraseMessageBox(&machineMan->msgBoxWindow, 1);
Window_ClearAndCopyToVRAM(&machineMan->msgBoxWindow);
Window_Remove(&machineMan->msgBoxWindow);
Bg_ClearTilesRange(BG_LAYER_MAIN_1, 32 * (24 * (12 + 2) + 9 + 1), 0, machineMan->heapID);
Bg_FillTilemapRect(machineMan->bgConfig, BG_LAYER_MAIN_1, 0, 0, 0, 32, 32, 17);
Bg_ScheduleTilemapTransfer(machineMan->bgConfig, BG_LAYER_MAIN_1);
Bg_ToggleLayer(BG_LAYER_MAIN_1, 0);
Bg_SetPriority(BG_LAYER_MAIN_0, machineMan->bgMain0Priority);
Bg_SetPriority(BG_LAYER_MAIN_1, machineMan->bgMain1Priority);
}
static void RankingsMachine_InitSprites(RankingsMachineManager *machineMan)
{
int i;
SpriteResourceCapacities capacities = {
1, 1, 1, 1, 0, 0
};
static const SpriteTemplate spriteTemplates[] = {
{
.x = 126,
.y = 16,
.z = 0,
.animIdx = 0,
.priority = 0,
.plttIdx = 1,
.vramType = NNS_G2D_VRAM_TYPE_2DMAIN,
.resources = {
0x34D8,
0x34D8,
0x34D8,
0x34D8,
NULL,
NULL,
},
.bgPriority = 1,
.vramTransfer = FALSE,
},
{
.x = 74,
.y = 120,
.z = 0,
.animIdx = 1,
.priority = 1,
.plttIdx = 0,
.vramType = NNS_G2D_VRAM_TYPE_2DMAIN,
.resources = {
0x34D8,
0x34D8,
0x34D8,
0x34D8,
NULL,
NULL,
},
.bgPriority = 1,
.vramTransfer = FALSE,
},
};
SpriteResourceManager_SetCapacities(&machineMan->spriteManager, &capacities, 2, machineMan->heapID);
NARC *narc = NARC_ctor(NARC_INDEX_GRAPHIC__RANKING, machineMan->heapID);
SpriteResourceManager_LoadPalette(&machineMan->spriteManager, narc, 0, 0, 3, NNS_G2D_VRAM_TYPE_2DMAIN, 13528);
SpriteResourceManager_LoadCell(&machineMan->spriteManager, narc, 2, 0, 13528);
SpriteResourceManager_LoadAnimation(&machineMan->spriteManager, narc, 3, 0, 13528);
SpriteResourceManager_LoadTiles(&machineMan->spriteManager, narc, 1, 0, NNS_G2D_VRAM_TYPE_2DMAIN, 13528);
NARC_dtor(narc);
for (i = 0; i < 2; i++) {
machineMan->managedSprites[i] = SpriteResourceManager_CreateManagedSprite(&machineMan->spriteManager, &spriteTemplates[i]);
}
ManagedSprite_SetDrawFlag(machineMan->managedSprites[MANAGED_SPRITE_DELETE_WINDOW], FALSE);
}
static void RankingsMachine_FreeSprites(RankingsMachineManager *machineMan)
{
int i;
for (i = 0; i < 2; i++) {
if (machineMan->managedSprites[i] != NULL) {
Sprite_DeleteAndFreeResources(machineMan->managedSprites[i]);
}
}
SpriteResourceManager_Cleanup(&machineMan->spriteManager);
}
static void RankingsMachine_ShowRecordsList(RankingsMachineManager *machineMan, u16 startListPos, u16 startCursorPos)
{
int i, listEntriesCount;
listEntriesCount = machineMan->recordsCount + 1;
machineMan->stringList = StringList_New(listEntriesCount, machineMan->heapID);
Window_Add(machineMan->bgConfig, &machineMan->listWindow, 1, 4, 1, 24, listEntriesCount * 2, 13, 1);
Window_FillTilemap(&machineMan->listWindow, PIXEL_FILL(15));
for (i = 0; i < machineMan->recordsCount; i++) {
StringList_AddFromString(machineMan->stringList, machineMan->text.titles[i], i);
}
StringList_AddFromString(machineMan->stringList, machineMan->text.exit, 0xFFFF);
MI_CpuCopy8((void *)&sRankingsMachineListMenuTemplate, (void *)&(machineMan->listMenuTemplate), sizeof(ListMenuTemplate));
machineMan->listMenuTemplate.window = &(machineMan->listWindow);
machineMan->listMenuTemplate.choices = machineMan->stringList;
machineMan->listMenuTemplate.parent = (void *)machineMan;
machineMan->listMenuTemplate.count = listEntriesCount;
machineMan->listMenuTemplate.yOffset = 0;
machineMan->listMenuTemplate.cursorCallback = RankingsMachine_SetCursorPos;
machineMan->listMenuTemplate.printCallback = NULL;
machineMan->listMenu = ListMenu_New(&(machineMan->listMenuTemplate), startListPos, startCursorPos, machineMan->heapID);
Window_DrawStandardFrame(&machineMan->listWindow, 0, BASE_TILE_STANDARD_WINDOW_FRAME, 11);
Window_DrawMessageBoxWithScrollCursor(&machineMan->msgBoxWindow, 1, BASE_TILE_SCROLLING_MESSAGE_BOX, 10);
Window_FillTilemap(&machineMan->msgBoxWindow, PIXEL_FILL(15));
Text_AddPrinterWithParamsAndColor(&machineMan->msgBoxWindow, FONT_MESSAGE, machineMan->text.whichRecord, 0, 0, TEXT_SPEED_INSTANT, TEXT_COLOR(1, 2, 15), NULL);
ManagedSprite_SetDrawFlag(machineMan->managedSprites[MANAGED_SPRITE_CURSOR], TRUE);
Bg_ScheduleTilemapTransfer(machineMan->bgConfig, BG_LAYER_MAIN_3);
}
static void RankingsMachine_RemoveRecordsList(RankingsMachineManager *machineMan)
{
ListMenu_Free(machineMan->listMenu, &(machineMan->startListPos), &(machineMan->startCursorPos));
StringList_Free(machineMan->stringList);
Window_ClearAndCopyToVRAM(&(machineMan->listWindow));
Window_EraseStandardFrame(&(machineMan->listWindow), 0);
Window_Remove(&(machineMan->listWindow));
ManagedSprite_SetDrawFlag(machineMan->managedSprites[MANAGED_SPRITE_CURSOR], FALSE);
Bg_ScheduleTilemapTransfer(machineMan->bgConfig, BG_LAYER_MAIN_3);
}
static void RankingsMachine_SetCursorPos(ListMenu *listMenu, u32 unused, u8 mute)
{
u16 listPos, cursorPos, count;
RankingsMachineManager *machineMan = (RankingsMachineManager *)ListMenu_GetAttribute(listMenu, LIST_MENU_PARENT);
if (mute == 0) {
Sound_PlayEffect(SEQ_SE_CONFIRM);
}
ListMenu_GetListAndCursorPos(listMenu, &listPos, &cursorPos);
count = ListMenu_GetAttribute(listMenu, LIST_MENU_COUNT);
ManagedSprite_SetPositionXY(machineMan->managedSprites[MANAGED_SPRITE_CURSOR], 126, 16 + 16 * (cursorPos + listPos));
}
static void RankingsMachine_PrintDeleteInstruction(RankingsMachineManager *machineMan)
{
Window_FillTilemap(&machineMan->msgBoxWindow, PIXEL_FILL(15));
Text_AddPrinterWithParamsAndColor(&machineMan->msgBoxWindow, FONT_MESSAGE, machineMan->text.deleteInstructions[0], 0, 0, TEXT_SPEED_INSTANT, TEXT_COLOR(1, 2, 15), NULL);
}
static void RankingsMachine_PrepareForDeletingRecord(RankingsMachineManager *machineMan)
{
RankingsMachine_PrintDeleteInstruction(machineMan);
ManagedSprite_SetPositionXY(machineMan->managedSprites[MANAGED_SPRITE_CURSOR], 126, 16 + machineMan->cursorPos * 16);
ManagedSprite_SetDrawFlag(machineMan->managedSprites[MANAGED_SPRITE_CURSOR], TRUE);
}
static void RankingsMachine_PrintRecordExplanation(RankingsMachineManager *machineMan)
{
Window_FillTilemap(&machineMan->msgBoxWindow, PIXEL_FILL(15));
Text_AddPrinterWithParamsAndColor(&machineMan->msgBoxWindow, FONT_MESSAGE, machineMan->text.explanations[machineMan->selectedRecordID], 0, 0, TEXT_SPEED_INSTANT, TEXT_COLOR(1, 2, 15), NULL);
ManagedSprite_SetDrawFlag(machineMan->managedSprites[MANAGED_SPRITE_CURSOR], FALSE);
}
static void RankingsMachine_PrintRecordRankings(RankingsMachineManager *machineMan, BOOL showDeleteScreen)
{
int i, unused, rank, rankingID, recordValue, prevRecordValue;
MachineRankings *machineRankings;
const RecordPrintingData *printingData;
machineRankings = &(machineMan->machineRankings[machineMan->selectedRecordID]);
printingData = &(sRecordsPrintingData[machineMan->listID][machineMan->selectedRecordID]);
Window_FillTilemap(&machineMan->listWindow, PIXEL_FILL(15));
unused = machineRankings->rankingsCount;
rank = 1;
rankingID = 0;
prevRecordValue = 0;
for (i = 0; i < machineRankings->rankingsCount; i++) {
if (!machineRankings->rankingsInfo[i].exists) {
continue;
}
recordValue = machineRankings->rankingsInfo[i].playerInfo->recordValue;
if (recordValue > printingData->maxScore) {
recordValue = printingData->maxScore;
}
if (recordValue < prevRecordValue) {
++rank;
}
StringTemplate_SetNumber(machineMan->text.strTemplate, 0, rank, 1, PADDING_MODE_SPACES, CHARSET_MODE_EN);
StringTemplate_SetString(machineMan->text.strTemplate, 1, machineRankings->rankingsInfo[i].playerInfo->playerName, 2, 1, GAME_LANGUAGE);
StringTemplate_Format(machineMan->text.strTemplate, machineMan->text.strBuffer, machineMan->text.recordEntryInfo);
Text_AddPrinterWithParamsAndColor(&machineMan->listWindow, FONT_SYSTEM, machineMan->text.strBuffer, 8, rankingID * 16, TEXT_SPEED_NO_TRANSFER, TEXT_COLOR(1, 2, 15), NULL);
StringTemplate_SetNumber(machineMan->text.strTemplate, 0, recordValue, printingData->maxDigits, PADDING_MODE_SPACES, CHARSET_MODE_EN);
StringTemplate_Format(machineMan->text.strTemplate, machineMan->text.strBuffer, machineMan->text.values[printingData->valueString - 15]);
Text_AddPrinterWithParamsAndColor(&machineMan->listWindow, FONT_SYSTEM, machineMan->text.strBuffer, (24 * 8) - Font_CalcStringWidth(FONT_SYSTEM, machineMan->text.strBuffer, 0) - 8, rankingID * 16, TEXT_SPEED_NO_TRANSFER, TEXT_COLOR(1, 2, 15), NULL);
machineMan->rankingIDs[rankingID] = i;
prevRecordValue = recordValue;
if (++rankingID >= MAX_RANKINGS_ENTRIES) {
break;
}
}
Window_CopyToVRAM(&machineMan->listWindow);
machineMan->lastRankingID = rankingID;
if (machineMan->cursorPos > 0 && machineMan->cursorPos >= machineMan->lastRankingID) {
machineMan->cursorPos--;
}
if (showDeleteScreen) {
RankingsMachine_PrepareForDeletingRecord(machineMan);
} else {
RankingsMachine_PrintRecordExplanation(machineMan);
}
}
static void RankingsMachine_ShowRankingList(RankingsMachineManager *machineMan, u16 cursorPos)
{
Window_Add(machineMan->bgConfig, &machineMan->listWindow, BG_LAYER_MAIN_1, 4, 1, 24, 12, 13, 1);
Window_DrawStandardFrame(&machineMan->listWindow, 1, BASE_TILE_STANDARD_WINDOW_FRAME, 11);
RankingsMachine_PrintRecordRankings(machineMan, FALSE);
ManagedSprite_SetDrawFlag(machineMan->managedSprites[MANAGED_SPRITE_DELETE_WINDOW], TRUE);
Window_Add(machineMan->bgConfig, &machineMan->rankingsWindow, BG_LAYER_MAIN_3, 8, 14, 8, 2, 13, BASE_TILE_RANKINGS_WINDOW);
Window_FillTilemap(&machineMan->rankingsWindow, PIXEL_FILL(0));
Text_AddPrinterWithParamsAndColor(&machineMan->rankingsWindow, FONT_SYSTEM, machineMan->text.deleteRecord, 0, 0, TEXT_SPEED_INSTANT, TEXT_COLOR(1, 2, 0), NULL);
Bg_ScheduleTilemapTransfer(machineMan->bgConfig, BG_LAYER_MAIN_3);
}
static void RankingsMachine_RemoveRankingList(RankingsMachineManager *machineMan)
{
Window_ClearAndCopyToVRAM(&machineMan->listWindow);
Window_EraseStandardFrame(&machineMan->listWindow, 0);
Window_Remove(&machineMan->listWindow);
Window_ClearAndCopyToVRAM(&machineMan->rankingsWindow);
Window_Remove(&machineMan->rankingsWindow);
ManagedSprite_SetDrawFlag(machineMan->managedSprites[MANAGED_SPRITE_CURSOR], FALSE);
ManagedSprite_SetDrawFlag(machineMan->managedSprites[MANAGED_SPRITE_DELETE_WINDOW], FALSE);
}
static BOOL RankingsMachine_Show(FieldTask *task)
{
FieldSystem *fieldSystem = FieldTask_GetFieldSystem(task);
RankingsMachine *rankingsMachine = FieldTask_GetEnv(task);
RankingsMachineManager *machineMan = rankingsMachine->manager;
switch (rankingsMachine->state) {
case STATE_INIT_MANAGER:
rankingsMachine->state = RankingsMachine_InitManager(rankingsMachine, fieldSystem, rankingsMachine->id);
break;
case STATE_INIT:
rankingsMachine->state = RankingsMachine_Init(rankingsMachine->manager, fieldSystem->saveData);
break;
case STATE_PRINT_RECORD_TITLES:
rankingsMachine->state = RankingsMachine_StateShowRecordsList(rankingsMachine->manager);
SpriteList_Update(rankingsMachine->manager->spriteManager.spriteList);
break;
case STATE_HANDLE_RECORDS_LIST_INPUT:
rankingsMachine->state = RankingsMachine_HandleRecordsListInput(rankingsMachine->manager);
SpriteList_Update(rankingsMachine->manager->spriteManager.spriteList);
break;
case STATE_SHOW_RANKINGS_LIST:
rankingsMachine->state = RankingsMachine_StateShowRankingList(rankingsMachine->manager);
SpriteList_Update(rankingsMachine->manager->spriteManager.spriteList);
break;
case STATE_HANDLE_RANKINGS_LIST_INPUT:
rankingsMachine->state = RankingsMachine_HandleRankingListInput(rankingsMachine->manager);
SpriteList_Update(rankingsMachine->manager->spriteManager.spriteList);
break;
case STATE_HANDLE_DELETE_RANKINGS_INPUT:
rankingsMachine->state = RankingsMachine_HandleDeleteRankingInput(rankingsMachine->manager);
SpriteList_Update(rankingsMachine->manager->spriteManager.spriteList);
break;
case STATE_ASK_DELETE_RANKING:
rankingsMachine->state = RankingsMachine_AskDeleteRanking(rankingsMachine->manager);
SpriteList_Update(rankingsMachine->manager->spriteManager.spriteList);
break;
case STATE_CANT_DELETE_OWN_RANKING:
rankingsMachine->state = RankingsMachine_CantDeleteOwnRanking(machineMan);
SpriteList_Update(rankingsMachine->manager->spriteManager.spriteList);
break;
case STATE_UNUSED:
if (!(JOY_NEW(PAD_BUTTON_A))) {
return FALSE;
}
rankingsMachine->state = STATE_FREE;
break;
case STATE_FREE:
rankingsMachine->state = RankingsMachine_Free(rankingsMachine->manager);
break;
case STATE_FREE_MANAGER:
rankingsMachine->state = RankingsMachine_FreeManager(rankingsMachine);
break;
case STATE_FREE_MACHINE:
Heap_Free(rankingsMachine);
return TRUE;
}
return FALSE;
}
void RankingsMachine_InitFieldTask(FieldTask *task, u16 machineID)
{
FieldSystem *fieldSystem = FieldTask_GetFieldSystem(task);
RankingsMachine *rankingsMachine = Heap_Alloc(HEAP_ID_FIELD2, sizeof(RankingsMachine));
rankingsMachine->state = STATE_INIT_MANAGER;
rankingsMachine->id = machineID;
rankingsMachine->manager = NULL;
FieldTask_InitCall(fieldSystem->task, RankingsMachine_Show, rankingsMachine);
}

View File

@ -21,6 +21,7 @@
#include "poffin.h"
#include "pokedex.h"
#include "poketch.h"
#include "rankings.h"
#include "record_mixed_rng.h"
#include "save_player.h"
#include "savedata.h"
@ -36,7 +37,6 @@
#include "unk_0202C9F4.h"
#include "unk_0202D778.h"
#include "unk_0202E2CC.h"
#include "unk_0202E840.h"
#include "unk_0202EEC0.h"
#include "unk_0202F1D4.h"
#include "unk_0203061C.h"

View File

@ -136,6 +136,7 @@
#include "pokemon.h"
#include "pokeradar.h"
#include "poketch.h"
#include "rankings_machine.h"
#include "render_window.h"
#include "roaming_pokemon.h"
#include "rtc.h"
@ -209,7 +210,6 @@
#include "unk_020655F4.h"
#include "unk_02069BE0.h"
#include "unk_0206C660.h"
#include "unk_0206F314.h"
#include "unk_02070428.h"
#include "unk_020722AC.h"
#include "unk_0207DA28.h"
@ -549,7 +549,7 @@ 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_1B5(ScriptContext *ctx);
static BOOL ScrCmd_StartRankingsMachine(ScriptContext *ctx);
static BOOL ScrCmd_GetTimeOfDay(ScriptContext *ctx);
static BOOL ScrCmd_GetRandom(ScriptContext *ctx);
static BOOL ScrCmd_GetRandom2(ScriptContext *ctx);
@ -1202,7 +1202,7 @@ const ScrCmdFunc Unk_020EAC58[] = {
ScrCmd_HideObject,
ScrCmd_1B3,
ScrCmd_1B4,
ScrCmd_1B5,
ScrCmd_StartRankingsMachine,
ScrCmd_GetTimeOfDay,
ScrCmd_GetRandom,
ScrCmd_GetRandom2,
@ -5767,11 +5767,11 @@ static BOOL ScrCmd_1B4(ScriptContext *ctx)
return FALSE;
}
static BOOL ScrCmd_1B5(ScriptContext *ctx)
static BOOL ScrCmd_StartRankingsMachine(ScriptContext *ctx)
{
u16 listIndex = ScriptContext_GetVar(ctx);
u16 machineID = ScriptContext_GetVar(ctx);
sub_020703FC(ctx->task, listIndex);
RankingsMachine_InitFieldTask(ctx->task, machineID);
return TRUE;
}

View File

@ -67,7 +67,7 @@ void TrainerCard_Init(u8 badgesInteractable, u8 liveTimeDisplay, u8 gymLeadersTo
TrainerCard_SetDates(SystemFlag_CheckGameCompleted(SaveData_GetVarsFlags(fieldSystem->saveData)), playTime, &adventureStartedDate, &firstCompletionDate, &firstCompletionTime, liveTimeDisplay, trainerCard);
TrainerCardSaveData *tcSaveData = SaveData_GetTrainerCardSaveData(fieldSystem->saveData);
u32 timesLinked = GameRecords_GetRecordValue(gameRecords, RECORD_UNK_091) + GameRecords_GetRecordValue(gameRecords, RECORD_LOCAL_LINK_TRADES) + GameRecords_GetRecordValue(gameRecords, RECORD_WIFI_TRADES) + GameRecords_GetRecordValue(gameRecords, RECORD_UNK_020) + GameRecords_GetRecordValue(gameRecords, RECORD_UNK_025) + GameRecords_GetRecordValue(gameRecords, RECORD_UNK_032);
u32 timesLinked = GameRecords_GetRecordValue(gameRecords, RECORD_LINK_CONTEST_PARTICIPATIONS) + GameRecords_GetRecordValue(gameRecords, RECORD_LOCAL_LINK_TRADES) + GameRecords_GetRecordValue(gameRecords, RECORD_WIFI_TRADES) + GameRecords_GetRecordValue(gameRecords, RECORD_UNK_020) + GameRecords_GetRecordValue(gameRecords, RECORD_UNK_025) + GameRecords_GetRecordValue(gameRecords, RECORD_UNK_032);
u32 linkBattleWins = GameRecords_GetRecordValue(gameRecords, RECORD_LOCAL_LINK_BATTLE_WINS) + GameRecords_GetRecordValue(gameRecords, RECORD_WIFI_BATTLE_WINS);
u32 linkBattleLosses = GameRecords_GetRecordValue(gameRecords, RECORD_LOCAL_LINK_BATTLE_LOSSES) + GameRecords_GetRecordValue(gameRecords, RECORD_WIFI_BATTLE_LOSSES);
u32 linkTrades = GameRecords_GetRecordValue(gameRecords, RECORD_LOCAL_LINK_TRADES) + GameRecords_GetRecordValue(gameRecords, RECORD_WIFI_TRADES);

View File

@ -1,452 +0,0 @@
#include "unk_0202E840.h"
#include <nitro.h>
#include <string.h>
#include "generated/game_records.h"
#include "struct_defs/battle_frontier.h"
#include "struct_defs/struct_0202E858.h"
#include "struct_defs/struct_0202E8C0.h"
#include "struct_defs/struct_0202E91C.h"
#include "struct_defs/struct_0202EA80.h"
#include "struct_defs/struct_0202EE10.h"
#include "charcode_util.h"
#include "game_records.h"
#include "heap.h"
#include "record_mixed_rng.h"
#include "save_player.h"
#include "savedata.h"
#include "string_gf.h"
#include "trainer_info.h"
#include "unk_0203061C.h"
typedef struct {
int unk_00;
int unk_04;
int unk_08;
UnkStruct_0202E858 *unk_0C[11];
UnkStruct_0202E858 *unk_38[6];
UnkStruct_0202EA80 unk_50;
} UnkStruct_0202EABC;
static const u8 Unk_020E5CD0[][2] = {
{ 0x6, 0x0 },
{ 0x4, 0x6 },
{ 0x3, 0xA }
};
u8 sub_0202E840(int param0)
{
return Unk_020E5CD0[param0][0];
}
u8 sub_0202E84C(int param0)
{
return Unk_020E5CD0[param0][1];
}
void sub_0202E858(UnkStruct_0202E858 *param0)
{
param0->unk_00 = 0;
param0->unk_04 = 0;
CharCode_FillWithEOS(param0->unk_08, 7 + 1);
SaveData_SetChecksum(SAVE_TABLE_ENTRY_RANKINGS);
}
BOOL sub_0202E870(UnkStruct_0202E858 *param0)
{
if (CharCode_Length(param0->unk_08) == 0) {
return 0;
}
return 1;
}
int Rankings_SaveSize(void)
{
return sizeof(UnkStruct_0202E8C0);
}
void Rankings_Init(UnkStruct_0202E8C0 *param0)
{
int v0, v1;
MI_CpuClear8(param0, sizeof(UnkStruct_0202E8C0));
for (v0 = 0; v0 < (13 * 2); v0++) {
for (v1 = 0; v1 < 6; v1++) {
sub_0202E858(&(param0->unk_00[v0].unk_00[v1]));
}
}
SaveData_SetChecksum(SAVE_TABLE_ENTRY_RANKINGS);
}
UnkStruct_0202E8C0 *sub_0202E8C0(SaveData *saveData)
{
SaveData_Checksum(SAVE_TABLE_ENTRY_RANKINGS);
return SaveData_SaveTable(saveData, SAVE_TABLE_ENTRY_RANKINGS);
}
void sub_0202E8D4(UnkStruct_0202E8C0 *param0, int param1, u8 param2)
{
int v0;
UnkStruct_0202EA80 *v1;
if (param2 >= 6) {
GF_ASSERT(param2 < 6);
return;
}
v1 = &(param0->unk_00[param1]);
for (v0 = param2; v0 < (6 - 1); v0++) {
v1->unk_00[v0] = v1->unk_00[v0 + 1];
}
sub_0202E858(&(v1->unk_00[6 - 1]));
SaveData_SetChecksum(SAVE_TABLE_ENTRY_RANKINGS);
}
int sub_0202E91C(void)
{
return sizeof(UnkStruct_0202E91C);
}
static u32 *sub_0202E924(SaveData *saveData, enum HeapID heapID)
{
int v0;
u32 v1;
GameRecords *v2;
BattleFrontier *frontier;
u32 *v4;
static const int v5[] = {
0x0,
0x2,
0x4,
0x6,
0x8,
0x1D,
0x29,
0x9,
0xB,
0xA,
0x5C,
0x5A,
0x5E
};
v2 = SaveData_GetGameRecords(saveData);
frontier = SaveData_GetBattleFrontier(saveData);
v4 = Heap_AllocAtEnd(heapID, 4 * 13);
for (v0 = 0; v0 < 13; v0++) {
switch (v0) {
case 5:
v1 = GameRecords_GetRecordValue(v2, RECORD_UNK_015);
if (v1 > 0) {
v1 = GameRecords_GetRecordValue(v2, RECORD_UNK_029) / v1;
}
v4[v0] = v1;
break;
case 10:
v1 = GameRecords_GetRecordValue(v2, RECORD_SUPER_CONTEST_WINS);
v1 += GameRecords_GetRecordValue(v2, RECORD_LINK_CONTEST_WINS);
v4[v0] = v1;
break;
case 11:
v1 = GameRecords_GetRecordValue(v2, RECORD_UNK_090);
v1 += GameRecords_GetRecordValue(v2, RECORD_UNK_091);
if (v1 > 0) {
v1 = (v4[10] * 100) / v1;
}
v4[v0] = v1;
break;
default:
if ((v0 >= 0) && (v0 <= 4)) {
v4[v0] = sub_02030698(frontier, v5[v0], 0xff);
} else {
v4[v0] = GameRecords_GetRecordValue(v2, v5[v0]);
}
}
}
SaveData_SetChecksum(SAVE_TABLE_ENTRY_RANKINGS);
return v4;
}
void *sub_0202E9FC(SaveData *saveData, enum HeapID heapID)
{
int v0;
u32 v1, v2;
UnkStruct_0202E91C *v3;
String *v4;
TrainerInfo *v5 = SaveData_GetTrainerInfo(saveData);
u32 *v6;
v3 = Heap_AllocAtEnd(heapID, sizeof(UnkStruct_0202E91C));
MI_CpuClear8(v3, sizeof(UnkStruct_0202E91C));
v1 = RecordMixedRNG_GetEntrySeed(SaveData_GetRecordMixedRNG(saveData), 1);
v4 = TrainerInfo_NameNewString(v5, heapID);
v6 = sub_0202E924(saveData, heapID);
for (v0 = 0; v0 < 13; v0++) {
v2 = 0;
v3->unk_00[v0].unk_00 = v1;
String_ToChars(v4, v3->unk_00[v0].unk_08, 7 + 1);
v3->unk_00[v0].unk_04 = v6[v0];
}
Heap_Free(v6);
String_Free(v4);
SaveData_SetChecksum(SAVE_TABLE_ENTRY_RANKINGS);
return v3;
}
static void sub_0202EA80(UnkStruct_0202EA80 *param0)
{
int v0;
for (v0 = 0; v0 < 6; v0++) {
sub_0202E858(&(param0->unk_00[v0]));
}
}
static BOOL sub_0202EA98(const UnkStruct_0202E858 *param0, const UnkStruct_0202E858 *param1)
{
if (param0->unk_00 != param1->unk_00) {
return 0;
}
if (CharCode_Compare(param0->unk_08, param1->unk_08)) {
return 0;
}
return 1;
}
static BOOL sub_0202EABC(UnkStruct_0202EABC *param0, const UnkStruct_0202E858 *param1)
{
int v0;
for (v0 = 0; v0 < param0->unk_04; v0++) {
if (sub_0202EA98(param0->unk_0C[v0], param1)) {
return 1;
}
}
return 0;
}
static void sub_0202EAEC(UnkStruct_0202E8C0 *param0, UnkStruct_0202EABC *param1, u32 param2, u8 param3, u8 param4, UnkStruct_0202E91C **param5, u8 param6, enum HeapID heapID)
{
int v0, v1;
UnkStruct_0202E858 *v2;
UnkStruct_0202EA80 *v3;
MI_CpuClear8(param1, sizeof(UnkStruct_0202EABC));
if (param4 == 0) {
v3 = &(param0->unk_00[param3]);
MI_CpuCopy8(v3, &(param1->unk_50), sizeof(UnkStruct_0202EA80));
for (v0 = 0; v0 < param6; v0++) {
param1->unk_0C[param1->unk_04++] = &(param5[v0]->unk_00[param3]);
}
for (v0 = 0; v0 < 6; v0++) {
if (!sub_0202E870(&(param1->unk_50.unk_00[v0]))) {
continue;
}
if (sub_0202EABC(param1, &(param1->unk_50.unk_00[v0]))) {
continue;
}
param1->unk_38[param1->unk_00++] = &(param1->unk_50.unk_00[v0]);
}
} else {
v3 = &(param0->unk_00[param3 + 13]);
MI_CpuCopy8(v3, &(param1->unk_50), sizeof(UnkStruct_0202EA80));
for (v0 = 0; v0 < param6; v0++) {
if ((param5[v0]->unk_00[param3].unk_00 == 0) || (param5[v0]->unk_00[param3].unk_00 != param2)) {
continue;
}
param1->unk_0C[param1->unk_04++] = &(param5[v0]->unk_00[param3]);
}
for (v0 = 0; v0 < 6; v0++) {
if (!sub_0202E870(&(param1->unk_50.unk_00[v0]))) {
continue;
}
if (param1->unk_50.unk_00[v0].unk_00 != param2) {
continue;
}
if (sub_0202EABC(param1, &(param1->unk_50.unk_00[v0]))) {
continue;
}
param1->unk_38[param1->unk_00++] = &(param1->unk_50.unk_00[v0]);
}
}
param1->unk_08 = param1->unk_04 + param1->unk_00;
for (v0 = 0; v0 < param1->unk_00; v0++) {
param1->unk_0C[v0 + param1->unk_04] = param1->unk_38[v0];
}
for (v0 = 0; v0 < (param1->unk_08 - 1); v0++) {
for (v1 = (param1->unk_08 - 1); v1 > v0; v1--) {
if (param1->unk_0C[v0]->unk_04 >= param1->unk_0C[v1]->unk_04) {
continue;
}
v2 = param1->unk_0C[v0];
param1->unk_0C[v0] = param1->unk_0C[v1];
param1->unk_0C[v1] = v2;
}
}
sub_0202EA80(v3);
for (v0 = 0; (v0 < 6 && v0 < param1->unk_08); v0++) {
v3->unk_00[v0] = *(param1->unk_0C[v0]);
}
}
static void sub_0202ECB0(UnkStruct_0202E8C0 *param0, u32 param1, u8 param2, UnkStruct_0202E91C **param3, u8 param4, enum HeapID heapID)
{
int v0, v1;
UnkStruct_0202EABC *v2 = Heap_AllocAtEnd(heapID, sizeof(UnkStruct_0202EABC));
sub_0202EAEC(param0, v2, param1, param2, 0, param3, param4, heapID);
if (param1 != 0) {
sub_0202EAEC(param0, v2, param1, param2, 1, param3, param4, heapID);
}
Heap_Free(v2);
}
void sub_0202ED0C(SaveData *saveData, int param1, u8 param2, const void **param3, enum HeapID heapID)
{
u8 v0, v1;
u32 v2;
UnkStruct_0202E91C *v3[5];
UnkStruct_0202E8C0 *v4;
UnkStruct_0202EE10 *v5;
v4 = sub_0202E8C0(saveData);
v2 = RecordMixedRNG_GetEntrySeed(SaveData_GetRecordMixedRNG(saveData), 1);
v1 = 0;
for (v0 = 0; v0 < param2; v0++) {
if (v0 == param1) {
continue;
}
if (param3[v0] == NULL) {
continue;
}
v3[v1++] = (UnkStruct_0202E91C *)param3[v0];
}
if (v1 == 0) {
return;
}
for (v0 = 0; v0 < 13; v0++) {
sub_0202ECB0(v4, v2, v0, v3, v1, heapID);
}
SaveData_SetChecksum(SAVE_TABLE_ENTRY_RANKINGS);
return;
}
UnkStruct_0202EE10 *sub_0202ED8C(SaveData *saveData, int param1, enum HeapID heapID)
{
int v0, v1;
u32 v2;
UnkStruct_0202EE10 *v3;
u32 *v4;
TrainerInfo *v5 = SaveData_GetTrainerInfo(saveData);
v3 = Heap_Alloc(heapID, sizeof(UnkStruct_0202EE10));
MI_CpuClear8(v3, sizeof(UnkStruct_0202EE10));
v2 = RecordMixedRNG_GetEntrySeed(SaveData_GetRecordMixedRNG(saveData), 1);
v4 = sub_0202E924(saveData, heapID);
v3->unk_00 = sub_0202E840(param1);
v1 = sub_0202E84C(param1);
for (v0 = 0; v0 < v3->unk_00; v0++) {
v3->unk_04[v0].unk_00 = v2;
v3->unk_04[v0].unk_04 = v4[v0 + v1];
v3->unk_04[v0].unk_08 = TrainerInfo_NameNewString(v5, heapID);
}
Heap_Free(v4);
return v3;
}
UnkStruct_0202EE10 *sub_0202EE10(UnkStruct_0202E8C0 *param0, int param1, enum HeapID heapID)
{
int v0;
UnkStruct_0202EE10 *v1;
UnkStruct_0202EA80 *v2;
v1 = Heap_Alloc(heapID, sizeof(UnkStruct_0202EE10));
MI_CpuClear8(v1, sizeof(UnkStruct_0202EE10));
v2 = &(param0->unk_00[param1]);
for (v0 = 0; v0 < 6; v0++) {
if (!sub_0202E870(&(v2->unk_00[v0]))) {
continue;
}
v1->unk_04[v1->unk_00].unk_00 = v2->unk_00[v0].unk_00;
v1->unk_04[v1->unk_00].unk_04 = v2->unk_00[v0].unk_04;
v1->unk_04[v1->unk_00].unk_08 = String_Init(7 + 1, heapID);
String_CopyChars(v1->unk_04[v1->unk_00].unk_08, v2->unk_00[v0].unk_08);
++v1->unk_00;
}
return v1;
}
void sub_0202EE8C(UnkStruct_0202EE10 *param0)
{
int v0;
for (v0 = 0; v0 < 6; v0++) {
if (param0->unk_04[v0].unk_08 != NULL) {
String_Free(param0->unk_04[v0].unk_08);
}
}
MI_CpuClear8(param0, sizeof(UnkStruct_0202EE10));
Heap_Free(param0);
param0 = NULL;
SaveData_SetChecksum(SAVE_TABLE_ENTRY_RANKINGS);
}

View File

@ -393,7 +393,7 @@ BattleTower *BattleTower_Init(SaveData *saveData, u16 param1, u16 challengeMode)
battleTower->roomNum = sub_0202D3B4(battleTower->unk_74, battleTower->challengeMode, 0);
}
battleTower->unk_20 = GameRecords_GetRecordValue(v5, RECORD_UNK_029);
battleTower->unk_20 = GameRecords_GetRecordValue(v5, RECORD_BATTLE_TOWER_VICTORIES);
}
if (battleTower->challengeMode == BATTLE_TOWER_MODE_6) {
@ -626,11 +626,11 @@ void BattleTower_UpdateGameRecords(BattleTower *battleTower, SaveData *saveData)
sub_0202D414(battleTower->unk_74, 8 + battleTower->challengeMode, 2);
}
GameRecords_AddToRecordValue(v5, RECORD_UNK_029, battleTower->unk_0D);
GameRecords_AddToRecordValue(v5, RECORD_BATTLE_TOWER_VICTORIES, battleTower->unk_0D);
sub_0202D3B4(battleTower->unk_74, battleTower->challengeMode, 2);
if (battleTower->challengeMode != BATTLE_TOWER_MODE_6) {
GameRecords_AddToRecordValue(SaveData_GetGameRecords(saveData), RECORD_UNK_015, 1);
GameRecords_AddToRecordValue(SaveData_GetGameRecords(saveData), RECORD_BATTLE_TOWER_CHALLENGES, 1);
}
sub_0204ACC8(battleTower);
@ -683,11 +683,11 @@ void BattleTower_UpdateGameRecordsAndJournal(BattleTower *battleTower, SaveData
v3 = sub_02030698(frontier, v1, sub_0205E6A8(v1));
v4 = sub_02030848(frontier, v1, sub_0205E6A8(v1), v0);
GameRecords_AddToRecordValue(v6, RECORD_UNK_029, 7);
GameRecords_AddToRecordValue(v6, RECORD_BATTLE_TOWER_VICTORIES, 7);
sub_0202D3B4(battleTower->unk_74, battleTower->challengeMode, 3);
if (battleTower->challengeMode != BATTLE_TOWER_MODE_6) {
GameRecords_AddToRecordValue(v6, RECORD_UNK_015, 1);
GameRecords_AddToRecordValue(v6, RECORD_BATTLE_TOWER_CHALLENGES, 1);
}
GameRecords_IncrementTrainerScore(v6, TRAINER_SCORE_EVENT_UNK_14);

View File

@ -1,909 +0,0 @@
#include "unk_0206F314.h"
#include <nitro.h>
#include <string.h>
#include "struct_decls/struct_0202E8C0_decl.h"
#include "struct_defs/struct_0202EE10.h"
#include "struct_defs/struct_0202EE10_sub1.h"
#include "field/field_system.h"
#include "overlay005/sprite_resource_manager.h"
#include "bg_window.h"
#include "field_task.h"
#include "font.h"
#include "game_options.h"
#include "heap.h"
#include "list_menu.h"
#include "menu.h"
#include "message.h"
#include "narc.h"
#include "render_window.h"
#include "save_player.h"
#include "savedata.h"
#include "sound_playback.h"
#include "sprite.h"
#include "sprite_system.h"
#include "string_gf.h"
#include "string_list.h"
#include "string_template.h"
#include "system.h"
#include "text.h"
#include "unk_0202E840.h"
typedef struct {
MessageLoader *unk_00;
StringTemplate *unk_04;
String *unk_08;
String *unk_0C;
String *unk_10;
String *unk_14;
String *unk_18;
String *unk_1C[7];
String *unk_38[6];
String *unk_50[6];
String *unk_68[3];
} UnkStruct_0206F7F8_sub1;
typedef struct {
UnkStruct_0202EE10_sub1 *unk_00;
u16 unk_04;
u8 unk_06;
} UnkStruct_0206F3A0;
typedef struct {
int unk_00;
UnkStruct_0206F3A0 unk_04[7];
} UnkStruct_02070050;
typedef struct {
u32 unk_00;
u16 unk_04;
u16 unk_06;
} UnkStruct_020F02D0;
typedef struct {
enum HeapID heapID;
int *unk_04;
int unk_08;
int unk_0C;
u16 unk_10;
u16 unk_12;
u16 unk_14;
u8 unk_16;
u8 unk_17;
u8 unk_18;
u8 unk_19;
u16 unk_1A;
u16 unk_1C;
u8 unk_1E;
u8 unk_1F;
u8 unk_20;
u8 unk_21;
u16 unk_22;
u16 unk_24;
u16 unk_26;
u16 unk_28;
UnkStruct_0206F7F8_sub1 unk_2C;
ListMenuTemplate unk_A0;
ListMenu *unk_C0;
StringList *unk_C4;
Menu *unk_C8;
FieldSystem *fieldSystem;
BgConfig *unk_D0;
Window unk_D4;
Window unk_E4;
Window unk_F4;
Window unk_104[3];
SpriteResourceManager spriteManager;
ManagedSprite *unk_2FC[2];
UnkStruct_0202E8C0 *unk_304;
UnkStruct_0202EE10 *unk_308[7];
UnkStruct_02070050 *unk_324;
UnkStruct_0206F3A0 *unk_328;
u8 unk_32C[6];
} UnkStruct_0206F7F8;
typedef struct {
int unk_00;
u16 unk_04;
UnkStruct_0206F7F8 *unk_08;
} UnkStruct_0206F314;
static void sub_0206F7F8(UnkStruct_0206F7F8 *param0, SaveData *saveData);
static void sub_0206F9D4(UnkStruct_0206F7F8 *param0);
static void sub_0206FA08(UnkStruct_0206F7F8 *param0);
static void sub_0206FAC0(UnkStruct_0206F7F8 *param0);
static void sub_0206FB38(UnkStruct_0206F7F8 *param0);
static void sub_0206FC4C(UnkStruct_0206F7F8 *param0);
static void sub_0206FCC4(UnkStruct_0206F7F8 *param0);
static void sub_0206FD94(UnkStruct_0206F7F8 *param0);
static void sub_0206FDC0(UnkStruct_0206F7F8 *param0, u16 param1, u16 param2);
static void sub_0206FF10(UnkStruct_0206F7F8 *param0);
static void sub_0206FF60(ListMenu *param0, u32 param1, u8 param2);
static void sub_0206FFB4(UnkStruct_0206F7F8 *param0);
static void sub_0206FFE4(UnkStruct_0206F7F8 *param0);
static void sub_02070010(UnkStruct_0206F7F8 *param0);
static void sub_02070050(UnkStruct_0206F7F8 *param0, BOOL param1);
static void sub_020701DC(UnkStruct_0206F7F8 *param0, u16 param1);
static void sub_02070288(UnkStruct_0206F7F8 *param0);
static const ListMenuTemplate Unk_020F02B0 = {
NULL,
NULL,
NULL,
NULL,
0x0,
0x7,
0x2,
0x8,
0x1,
0x0,
0x1,
0xF,
0x2,
0x0,
0x0,
0x1,
0x0,
0x1,
NULL
};
static const UnkStruct_020F02D0 Unk_020F02D0[] = {
{ 0x270F, 0x4, 0xF },
{ 0x270F, 0x4, 0xF },
{ 0x270F, 0x4, 0xF },
{ 0x270F, 0x4, 0xF },
{ 0x270F, 0x4, 0xF },
{ 0x7, 0x1, 0x10 }
};
static const UnkStruct_020F02D0 Unk_020F0290[] = {
{ 0xF423F, 0x6, 0x13 },
{ 0xF423F, 0x6, 0x13 },
{ 0xF423F, 0x6, 0x12 },
{ 0xF423F, 0x6, 0x13 }
};
static const UnkStruct_020F02D0 Unk_020F0278[] = {
{ 0x270F, 0x4, 0x15 },
{ 0x64, 0x4, 0x14 },
{ 0xFFFF, 0x5, 0x11 }
};
static const UnkStruct_020F02D0 *const Unk_020F0254[] = {
Unk_020F02D0,
Unk_020F0290,
Unk_020F0278
};
static int sub_0206F314(UnkStruct_0206F314 *param0, FieldSystem *fieldSystem, u16 param2)
{
UnkStruct_0206F7F8 *v0;
SaveData *saveData = fieldSystem->saveData;
Heap_Create(HEAP_ID_APPLICATION, HEAP_ID_80, 0x6000);
v0 = Heap_Alloc(HEAP_ID_80, sizeof(UnkStruct_0206F7F8));
MI_CpuClear8(v0, sizeof(UnkStruct_0206F7F8));
v0->heapID = HEAP_ID_80;
v0->unk_16 = param2 % 3;
v0->unk_17 = param2 / 3;
v0->unk_18 = sub_0202E840(v0->unk_16);
v0->unk_19 = sub_0202E84C(v0->unk_16);
v0->fieldSystem = fieldSystem;
v0->unk_D0 = fieldSystem->bgConfig;
v0->unk_304 = sub_0202E8C0(saveData);
v0->unk_1A = Options_TextFrameDelay(SaveData_GetOptions(saveData));
v0->unk_1C = Options_Frame(SaveData_GetOptions(saveData));
param0->unk_08 = v0;
return 1;
}
static int sub_0206F3A0(UnkStruct_0206F314 *param0)
{
int v0, v1, v2, heapID;
UnkStruct_0206F3A0 *v4;
UnkStruct_0206F7F8 *v5 = param0->unk_08;
for (v0 = 0; v0 < v5->unk_18; v0++) {
v2 = 0;
for (v1 = 0; v1 < v5->unk_324[v0].unk_00; v1++) {
v4 = &(v5->unk_324[v0].unk_04[v1]);
if ((v4->unk_06 == 0xFF) || v4->unk_04) {
continue;
}
sub_0202E8D4(v5->unk_304, (v5->unk_17 * 13) + v5->unk_19 + v0, v4->unk_06 - v2);
++v2;
}
}
heapID = v5->heapID;
Heap_Free(v5);
MI_CpuClear8(v5, sizeof(UnkStruct_0206F7F8));
Heap_Destroy(heapID);
return 12;
}
static int sub_0206F448(UnkStruct_0206F7F8 *param0, SaveData *saveData)
{
sub_0206F7F8(param0, saveData);
sub_0206FA08(param0);
sub_0206FB38(param0);
sub_0206FCC4(param0);
return 2;
}
static int sub_0206F468(UnkStruct_0206F7F8 *param0)
{
sub_0206FD94(param0);
sub_0206FC4C(param0);
sub_0206FAC0(param0);
sub_0206F9D4(param0);
return 11;
}
static int sub_0206F488(UnkStruct_0206F7F8 *param0)
{
sub_0206FDC0(param0, param0->unk_22, param0->unk_24);
return 3;
}
static int sub_0206F498(UnkStruct_0206F7F8 *param0)
{
s32 v0 = ListMenu_ProcessInput(param0->unk_C0);
if (gSystem.pressedKeys & PAD_BUTTON_B) {
Sound_PlayEffect(SEQ_SE_CONFIRM);
sub_0206FF10(param0);
return 10;
}
if (!(gSystem.pressedKeys & PAD_BUTTON_A)) {
return 3;
}
Sound_PlayEffect(SEQ_SE_CONFIRM);
switch (v0) {
case 0xffffffff:
case 0xfffffffe:
case 0xFFFF:
sub_0206FF10(param0);
return 10;
default:
param0->unk_1F = v0;
param0->unk_28 = 0;
sub_0206FF10(param0);
return 4;
}
return 3;
}
static int sub_0206F508(UnkStruct_0206F7F8 *param0)
{
sub_020701DC(param0, param0->unk_28);
return 5;
}
static int sub_0206F514(UnkStruct_0206F7F8 *param0)
{
if (gSystem.pressedKeys & (PAD_BUTTON_B | PAD_BUTTON_A)) {
Sound_PlayEffect(SEQ_SE_CONFIRM);
sub_02070288(param0);
return 2;
}
if (gSystem.pressedKeys & PAD_BUTTON_SELECT) {
Sound_PlayEffect(SEQ_SE_CONFIRM);
sub_0206FFE4(param0);
return 6;
}
return 5;
}
static int sub_0206F554(UnkStruct_0206F7F8 *param0)
{
UnkStruct_0206F3A0 *v0;
if (gSystem.pressedKeys & (PAD_BUTTON_B)) {
Sound_PlayEffect(SEQ_SE_CONFIRM);
sub_02070010(param0);
return 5;
}
if (gSystem.pressedKeys & PAD_BUTTON_A) {
Sound_PlayEffect(SEQ_SE_CONFIRM);
param0->unk_0C = 0;
param0->unk_328 = &(param0->unk_324[param0->unk_1F].unk_04[param0->unk_32C[param0->unk_28]]);
if (param0->unk_328->unk_06 == 0xFF) {
return 8;
}
return 7;
}
if (gSystem.pressedKeys & PAD_KEY_UP) {
if (param0->unk_28 > 0) {
Sound_PlayEffect(SEQ_SE_CONFIRM);
--param0->unk_28;
ManagedSprite_SetPositionXY(param0->unk_2FC[0], 126, 16 + 16 * param0->unk_28);
}
}
if (gSystem.pressedKeys & PAD_KEY_DOWN) {
if (param0->unk_28 < (param0->unk_21 - 1)) {
Sound_PlayEffect(SEQ_SE_CONFIRM);
++param0->unk_28;
ManagedSprite_SetPositionXY(param0->unk_2FC[0], 126, 16 + 16 * param0->unk_28);
}
}
return 6;
}
static void sub_0206F62C(UnkStruct_0206F7F8 *param0)
{
static const WindowTemplate v0 = {
0x3,
0x19,
0xD,
0x6,
0x4,
0xD,
0x355
};
param0->unk_C8 = Menu_MakeYesNoChoice(param0->unk_D0, &v0, (1024 - (18 + 12) - 9), 11, param0->heapID);
}
static int sub_0206F658(UnkStruct_0206F7F8 *param0)
{
int v0 = 0;
switch (param0->unk_0C) {
case 0:
Window_FillTilemap(&param0->unk_E4, ((15 << 4) | 15));
param0->unk_1E = Text_AddPrinterWithParamsAndColor(&param0->unk_E4, FONT_MESSAGE, param0->unk_2C.unk_68[1], 0, 0, param0->unk_1A, TEXT_COLOR(1, 2, 15), NULL);
ManagedSprite_SetExplicitPalette(param0->unk_2FC[0], 2);
param0->unk_0C++;
break;
case 1:
if (Text_IsPrinterActive(param0->unk_1E)) {
break;
}
sub_0206F62C(param0);
param0->unk_0C++;
break;
case 2:
switch (Menu_ProcessInputAndHandleExit(param0->unk_C8, param0->heapID)) {
case 0:
param0->unk_0C++;
break;
case 0xfffffffe:
param0->unk_0C = 0xFF;
break;
}
break;
case 3:
param0->unk_328->unk_04 = 0;
sub_02070050(param0, 1);
ManagedSprite_SetExplicitPalette(param0->unk_2FC[0], 1);
param0->unk_0C = 0;
return 6;
case 0xFF:
sub_0206FFB4(param0);
ManagedSprite_SetExplicitPalette(param0->unk_2FC[0], 1);
param0->unk_0C = 0;
return 6;
}
return 7;
}
static int sub_0206F748(UnkStruct_0206F7F8 *param0)
{
int v0 = 0;
switch (param0->unk_0C) {
case 0:
Sound_PlayEffect(SEQ_SE_DP_CUSTOM06);
Window_FillTilemap(&param0->unk_E4, ((15 << 4) | 15));
param0->unk_1E = Text_AddPrinterWithParamsAndColor(&param0->unk_E4, FONT_MESSAGE, param0->unk_2C.unk_68[2], 0, 0, param0->unk_1A, TEXT_COLOR(1, 2, 15), NULL);
ManagedSprite_SetExplicitPalette(param0->unk_2FC[0], 2);
param0->unk_0C++;
break;
case 1:
if (Text_IsPrinterActive(param0->unk_1E)) {
break;
}
param0->unk_0C++;
break;
case 2:
if (!(gSystem.pressedKeys & (PAD_BUTTON_A | PAD_BUTTON_B))) {
break;
}
Sound_PlayEffect(SEQ_SE_CONFIRM);
sub_0206FFB4(param0);
ManagedSprite_SetExplicitPalette(param0->unk_2FC[0], 1);
param0->unk_0C = 0;
return 6;
}
return 8;
}
static void sub_0206F7F8(UnkStruct_0206F7F8 *param0, SaveData *saveData)
{
int v0, v1, v2, v3;
UnkStruct_0202EE10 *v4;
param0->unk_324 = Heap_Alloc(param0->heapID, sizeof(UnkStruct_02070050) * param0->unk_18);
MI_CpuClear8(param0->unk_324, sizeof(UnkStruct_02070050) * param0->unk_18);
param0->unk_308[0] = sub_0202ED8C(saveData, param0->unk_16, param0->heapID);
for (v0 = 0; v0 < param0->unk_18; v0++) {
param0->unk_308[v0 + 1] = sub_0202EE10(param0->unk_304, (param0->unk_17 * 13) + param0->unk_19 + v0, param0->heapID);
v4 = param0->unk_308[v0 + 1];
v2 = 0;
v3 = 0;
if (v4->unk_00 == 0) {
param0->unk_324[v0].unk_04[0].unk_00 = &(param0->unk_308[0]->unk_04[v0]);
param0->unk_324[v0].unk_04[0].unk_04 = 1;
param0->unk_324[v0].unk_04[0].unk_06 = 0xFF;
param0->unk_324[v0].unk_00 = 1;
} else {
for (v1 = 0; v1 < v4->unk_00; v1++) {
if ((v3 == 0) && (param0->unk_308[0]->unk_04[v0].unk_04 >= v4->unk_04[v1].unk_04)) {
param0->unk_324[v0].unk_04[v2].unk_00 = &(param0->unk_308[0]->unk_04[v0]);
param0->unk_324[v0].unk_04[v2].unk_04 = 1;
param0->unk_324[v0].unk_04[v2].unk_06 = 0xFF;
++v2;
param0->unk_324[v0].unk_04[v2].unk_00 = &(v4->unk_04[v1]);
param0->unk_324[v0].unk_04[v2].unk_04 = 1;
param0->unk_324[v0].unk_04[v2].unk_06 = v1;
v3 = 1;
} else {
param0->unk_324[v0].unk_04[v2].unk_00 = &(v4->unk_04[v1]);
param0->unk_324[v0].unk_04[v2].unk_04 = 1;
param0->unk_324[v0].unk_04[v2].unk_06 = v1;
}
++v2;
}
if (!v3) {
param0->unk_324[v0].unk_04[v2].unk_00 = &(param0->unk_308[0]->unk_04[v0]);
param0->unk_324[v0].unk_04[v2].unk_04 = 1;
param0->unk_324[v0].unk_04[v2].unk_06 = 0xFF;
}
param0->unk_324[v0].unk_00 = v4->unk_00 + 1;
}
}
}
static void sub_0206F9D4(UnkStruct_0206F7F8 *param0)
{
int v0;
for (v0 = 0; v0 < param0->unk_18 + 1; v0++) {
sub_0202EE8C(param0->unk_308[v0]);
}
Heap_Free(param0->unk_324);
}
static void sub_0206FA08(UnkStruct_0206F7F8 *param0)
{
int v0;
param0->unk_2C.unk_00 = MessageLoader_Init(MSG_LOADER_PRELOAD_ENTIRE_BANK, NARC_INDEX_MSGDATA__PL_MSG, TEXT_BANK_UNK_0532, param0->heapID);
param0->unk_2C.unk_04 = StringTemplate_New(2, (38 * 2), param0->heapID);
param0->unk_2C.unk_08 = String_Init((38 * 2), param0->heapID);
param0->unk_2C.unk_0C = MessageLoader_GetNewString(param0->unk_2C.unk_00, 13);
param0->unk_2C.unk_10 = MessageLoader_GetNewString(param0->unk_2C.unk_00, 22);
param0->unk_2C.unk_14 = MessageLoader_GetNewString(param0->unk_2C.unk_00, 36);
param0->unk_2C.unk_18 = MessageLoader_GetNewString(param0->unk_2C.unk_00, 14);
for (v0 = 0; v0 < param0->unk_18; v0++) {
param0->unk_2C.unk_38[v0] = MessageLoader_GetNewString(param0->unk_2C.unk_00, 0 + param0->unk_19 + v0);
param0->unk_2C.unk_50[v0] = MessageLoader_GetNewString(param0->unk_2C.unk_00, 23 + param0->unk_19 + v0);
}
for (v0 = 0; v0 < 7; v0++) {
param0->unk_2C.unk_1C[v0] = MessageLoader_GetNewString(param0->unk_2C.unk_00, 15 + v0);
}
for (v0 = 0; v0 < 3; v0++) {
param0->unk_2C.unk_68[v0] = MessageLoader_GetNewString(param0->unk_2C.unk_00, 37 + v0);
}
}
static void sub_0206FAC0(UnkStruct_0206F7F8 *param0)
{
int v0;
for (v0 = 0; v0 < 3; v0++) {
String_Free(param0->unk_2C.unk_68[v0]);
}
for (v0 = 0; v0 < 7; v0++) {
String_Free(param0->unk_2C.unk_1C[v0]);
}
for (v0 = 0; v0 < param0->unk_18; v0++) {
String_Free(param0->unk_2C.unk_38[v0]);
String_Free(param0->unk_2C.unk_50[v0]);
}
String_Free(param0->unk_2C.unk_18);
String_Free(param0->unk_2C.unk_14);
String_Free(param0->unk_2C.unk_10);
String_Free(param0->unk_2C.unk_0C);
String_Free(param0->unk_2C.unk_08);
StringTemplate_Free(param0->unk_2C.unk_04);
MessageLoader_Free(param0->unk_2C.unk_00);
}
static void sub_0206FB38(UnkStruct_0206F7F8 *param0)
{
Bg_ClearTilesRange(BG_LAYER_MAIN_1, 32 * (24 * (12 + 2) + 9 + 1), 0, param0->heapID);
Bg_FillTilemapRect(param0->unk_D0, 1, 0x0, 0, 0, 32, 32, 17);
Bg_ScheduleTilemapTransfer(param0->unk_D0, 1);
Bg_ToggleLayer(BG_LAYER_MAIN_1, 1);
param0->unk_10 = Bg_GetPriority(param0->unk_D0, BG_LAYER_MAIN_0);
param0->unk_12 = Bg_GetPriority(param0->unk_D0, BG_LAYER_MAIN_1);
Bg_SetPriority(BG_LAYER_MAIN_0, 2);
Bg_SetPriority(BG_LAYER_MAIN_1, 1);
LoadMessageBoxGraphics(param0->unk_D0, BG_LAYER_MAIN_3, (1024 - (18 + 12)), 10, param0->unk_1C, param0->heapID);
LoadStandardWindowGraphics(param0->unk_D0, BG_LAYER_MAIN_3, (1024 - (18 + 12) - 9), 11, 0, param0->heapID);
LoadStandardWindowGraphics(param0->unk_D0, BG_LAYER_MAIN_1, (1024 - (18 + 12) - 9), 11, 0, param0->heapID);
Font_LoadTextPalette(0, 13 * 32, param0->heapID);
Font_LoadScreenIndicatorsPalette(0, 12 * 32, param0->heapID);
Window_Add(param0->unk_D0, &param0->unk_E4, 3, 2, 19, 27, 4, 12, ((1024 - (18 + 12) - 9) - 27 * 4));
Window_FillTilemap(&param0->unk_E4, ((15 << 4) | 15));
}
static void sub_0206FC4C(UnkStruct_0206F7F8 *param0)
{
Window_EraseMessageBox(&param0->unk_E4, 1);
Window_ClearAndCopyToVRAM(&param0->unk_E4);
Window_Remove(&param0->unk_E4);
Bg_ClearTilesRange(BG_LAYER_MAIN_1, 32 * (24 * (12 + 2) + 9 + 1), 0, param0->heapID);
Bg_FillTilemapRect(param0->unk_D0, 1, 0x0, 0, 0, 32, 32, 17);
Bg_ScheduleTilemapTransfer(param0->unk_D0, 1);
Bg_ToggleLayer(BG_LAYER_MAIN_1, 0);
Bg_SetPriority(BG_LAYER_MAIN_0, param0->unk_10);
Bg_SetPriority(BG_LAYER_MAIN_1, param0->unk_12);
}
static void sub_0206FCC4(UnkStruct_0206F7F8 *param0)
{
int v0;
SpriteResourceCapacities v1 = {
1, 1, 1, 1, 0, 0
};
static const SpriteTemplate v2[] = {
{
0x7E,
0x10,
0x0,
0x0,
0x0,
0x1,
NNS_G2D_VRAM_TYPE_2DMAIN,
{ 0x34D8, 0x34D8, 0x34D8, 0x34D8, 0x0, 0x0 },
0x1,
0x0,
},
{
0x4A,
0x78,
0x0,
0x1,
0x1,
0x0,
NNS_G2D_VRAM_TYPE_2DMAIN,
{ 0x34D8, 0x34D8, 0x34D8, 0x34D8, 0x0, 0x0 },
0x1,
0x0,
},
};
SpriteResourceManager_SetCapacities(&param0->spriteManager, &v1, 2, param0->heapID);
{
NARC *v3;
v3 = NARC_ctor(NARC_INDEX_GRAPHIC__RANKING, param0->heapID);
SpriteResourceManager_LoadPalette(&param0->spriteManager, v3, 0, 0, 3, NNS_G2D_VRAM_TYPE_2DMAIN, 13528);
SpriteResourceManager_LoadCell(&param0->spriteManager, v3, 2, 0, 13528);
SpriteResourceManager_LoadAnimation(&param0->spriteManager, v3, 3, 0, 13528);
SpriteResourceManager_LoadTiles(&param0->spriteManager, v3, 1, 0, NNS_G2D_VRAM_TYPE_2DMAIN, 13528);
NARC_dtor(v3);
}
for (v0 = 0; v0 < 2; v0++) {
param0->unk_2FC[v0] = SpriteResourceManager_CreateManagedSprite(&param0->spriteManager, &v2[v0]);
}
ManagedSprite_SetDrawFlag(param0->unk_2FC[1], 0);
}
static void sub_0206FD94(UnkStruct_0206F7F8 *param0)
{
int v0;
for (v0 = 0; v0 < 2; v0++) {
if (param0->unk_2FC[v0] != NULL) {
Sprite_DeleteAndFreeResources(param0->unk_2FC[v0]);
}
}
SpriteResourceManager_Cleanup(&param0->spriteManager);
}
static void sub_0206FDC0(UnkStruct_0206F7F8 *param0, u16 param1, u16 param2)
{
int v0, v1;
v1 = param0->unk_18 + 1;
param0->unk_C4 = StringList_New(v1, param0->heapID);
Window_Add(param0->unk_D0, &param0->unk_D4, 1, 4, 1, 24, v1 * 2, 13, 1);
Window_FillTilemap(&param0->unk_D4, ((15 << 4) | 15));
for (v0 = 0; v0 < param0->unk_18; v0++) {
StringList_AddFromString(param0->unk_C4, param0->unk_2C.unk_38[v0], v0);
}
StringList_AddFromString(param0->unk_C4, param0->unk_2C.unk_0C, 0xFFFF);
MI_CpuCopy8((void *)&Unk_020F02B0, (void *)&(param0->unk_A0), sizeof(ListMenuTemplate));
param0->unk_A0.window = &(param0->unk_D4);
param0->unk_A0.choices = param0->unk_C4;
param0->unk_A0.parent = (void *)param0;
param0->unk_A0.count = v1;
param0->unk_A0.yOffset = 0;
param0->unk_A0.cursorCallback = sub_0206FF60;
param0->unk_A0.printCallback = NULL;
param0->unk_C0 = ListMenu_New(&(param0->unk_A0), param1, param2, param0->heapID);
Window_DrawStandardFrame(&param0->unk_D4, 0, (1024 - (18 + 12) - 9), 11);
Window_DrawMessageBoxWithScrollCursor(&param0->unk_E4, 1, (1024 - (18 + 12)), 10);
Window_FillTilemap(&param0->unk_E4, ((15 << 4) | 15));
Text_AddPrinterWithParamsAndColor(&param0->unk_E4, FONT_MESSAGE, param0->unk_2C.unk_10, 0, 0, TEXT_SPEED_INSTANT, TEXT_COLOR(1, 2, 15), NULL);
ManagedSprite_SetDrawFlag(param0->unk_2FC[0], 1);
Bg_ScheduleTilemapTransfer(param0->unk_D0, 3);
}
static void sub_0206FF10(UnkStruct_0206F7F8 *param0)
{
ListMenu_Free(param0->unk_C0, &(param0->unk_22), &(param0->unk_24));
StringList_Free(param0->unk_C4);
Window_ClearAndCopyToVRAM(&(param0->unk_D4));
Window_EraseStandardFrame(&(param0->unk_D4), 0);
Window_Remove(&(param0->unk_D4));
ManagedSprite_SetDrawFlag(param0->unk_2FC[0], 0);
Bg_ScheduleTilemapTransfer(param0->unk_D0, 3);
}
static void sub_0206FF60(ListMenu *param0, u32 param1, u8 param2)
{
u16 v0, v1, v2;
UnkStruct_0206F7F8 *v3 = (UnkStruct_0206F7F8 *)ListMenu_GetAttribute(param0, 19);
if (param2 == 0) {
Sound_PlayEffect(SEQ_SE_CONFIRM);
}
ListMenu_GetListAndCursorPos(param0, &v0, &v1);
v2 = ListMenu_GetAttribute(param0, 2);
ManagedSprite_SetPositionXY(v3->unk_2FC[0], 126, 16 + 16 * (v1 + v0));
}
static void sub_0206FFB4(UnkStruct_0206F7F8 *param0)
{
Window_FillTilemap(&param0->unk_E4, ((15 << 4) | 15));
Text_AddPrinterWithParamsAndColor(&param0->unk_E4, FONT_MESSAGE, param0->unk_2C.unk_68[0], 0, 0, TEXT_SPEED_INSTANT, TEXT_COLOR(1, 2, 15), NULL);
}
static void sub_0206FFE4(UnkStruct_0206F7F8 *param0)
{
sub_0206FFB4(param0);
ManagedSprite_SetPositionXY(param0->unk_2FC[0], 126, 16 + param0->unk_28 * 16);
ManagedSprite_SetDrawFlag(param0->unk_2FC[0], 1);
}
static void sub_02070010(UnkStruct_0206F7F8 *param0)
{
Window_FillTilemap(&param0->unk_E4, ((15 << 4) | 15));
Text_AddPrinterWithParamsAndColor(&param0->unk_E4, FONT_MESSAGE, param0->unk_2C.unk_50[param0->unk_1F], 0, 0, TEXT_SPEED_INSTANT, TEXT_COLOR(1, 2, 15), NULL);
ManagedSprite_SetDrawFlag(param0->unk_2FC[0], 0);
}
static void sub_02070050(UnkStruct_0206F7F8 *param0, BOOL param1)
{
int v0, v1, v2, v3, v4, v5;
UnkStruct_02070050 *v6;
const UnkStruct_020F02D0 *v7;
v6 = &(param0->unk_324[param0->unk_1F]);
v7 = &(Unk_020F0254[param0->unk_16][param0->unk_1F]);
Window_FillTilemap(&param0->unk_D4, ((15 << 4) | 15));
v1 = v6->unk_00;
v2 = 1;
v3 = 0;
v5 = 0;
for (v0 = 0; v0 < v6->unk_00; v0++) {
if (!v6->unk_04[v0].unk_04) {
continue;
}
v4 = v6->unk_04[v0].unk_00->unk_04;
if (v4 > v7->unk_00) {
v4 = v7->unk_00;
}
if (v4 < v5) {
++v2;
}
StringTemplate_SetNumber(param0->unk_2C.unk_04, 0, v2, 1, 1, 1);
StringTemplate_SetString(param0->unk_2C.unk_04, 1, v6->unk_04[v0].unk_00->unk_08, 2, 1, GAME_LANGUAGE);
StringTemplate_Format(param0->unk_2C.unk_04, param0->unk_2C.unk_08, param0->unk_2C.unk_18);
Text_AddPrinterWithParamsAndColor(&param0->unk_D4, FONT_SYSTEM, param0->unk_2C.unk_08, 8, v3 * 16, TEXT_SPEED_NO_TRANSFER, TEXT_COLOR(1, 2, 15), NULL);
StringTemplate_SetNumber(param0->unk_2C.unk_04, 0, v4, v7->unk_04, 1, 1);
StringTemplate_Format(param0->unk_2C.unk_04, param0->unk_2C.unk_08, param0->unk_2C.unk_1C[v7->unk_06 - 15]);
Text_AddPrinterWithParamsAndColor(&param0->unk_D4, FONT_SYSTEM, param0->unk_2C.unk_08, (24 * 8) - Font_CalcStringWidth(FONT_SYSTEM, param0->unk_2C.unk_08, 0) - 8, v3 * 16, TEXT_SPEED_NO_TRANSFER, TEXT_COLOR(1, 2, 15), NULL);
param0->unk_32C[v3] = v0;
v5 = v4;
if (++v3 >= 6) {
break;
}
}
Window_CopyToVRAM(&param0->unk_D4);
param0->unk_21 = v3;
if ((param0->unk_28 > 0) && (param0->unk_28 >= param0->unk_21)) {
param0->unk_28--;
}
if (param1) {
sub_0206FFE4(param0);
} else {
sub_02070010(param0);
}
}
static void sub_020701DC(UnkStruct_0206F7F8 *param0, u16 param1)
{
Window_Add(param0->unk_D0, &param0->unk_D4, 1, 4, 1, 24, 12, 13, 1);
Window_DrawStandardFrame(&param0->unk_D4, 1, (1024 - (18 + 12) - 9), 11);
sub_02070050(param0, 0);
ManagedSprite_SetDrawFlag(param0->unk_2FC[1], 1);
Window_Add(param0->unk_D0, &param0->unk_F4, 3, 8, 14, 8, 2, 13, ((((1024 - (18 + 12) - 9) - 27 * 4) - 6 * 4) - (8 * 2)));
Window_FillTilemap(&param0->unk_F4, ((0 << 4) | 0));
Text_AddPrinterWithParamsAndColor(&param0->unk_F4, FONT_SYSTEM, param0->unk_2C.unk_14, 0, 0, TEXT_SPEED_INSTANT, TEXT_COLOR(1, 2, 0), NULL);
Bg_ScheduleTilemapTransfer(param0->unk_D0, 3);
}
static void sub_02070288(UnkStruct_0206F7F8 *param0)
{
Window_ClearAndCopyToVRAM(&param0->unk_D4);
Window_EraseStandardFrame(&param0->unk_D4, 0);
Window_Remove(&param0->unk_D4);
Window_ClearAndCopyToVRAM(&param0->unk_F4);
Window_Remove(&param0->unk_F4);
ManagedSprite_SetDrawFlag(param0->unk_2FC[0], 0);
ManagedSprite_SetDrawFlag(param0->unk_2FC[1], 0);
}
static BOOL sub_020702D0(FieldTask *param0)
{
FieldSystem *fieldSystem = FieldTask_GetFieldSystem(param0);
UnkStruct_0206F314 *v1 = FieldTask_GetEnv(param0);
UnkStruct_0206F7F8 *v2 = v1->unk_08;
switch (v1->unk_00) {
case 0:
v1->unk_00 = sub_0206F314(v1, fieldSystem, v1->unk_04);
break;
case 1:
v1->unk_00 = sub_0206F448(v1->unk_08, fieldSystem->saveData);
break;
case 2:
v1->unk_00 = sub_0206F488(v1->unk_08);
SpriteList_Update(v1->unk_08->spriteManager.spriteList);
break;
case 3:
v1->unk_00 = sub_0206F498(v1->unk_08);
SpriteList_Update(v1->unk_08->spriteManager.spriteList);
break;
case 4:
v1->unk_00 = sub_0206F508(v1->unk_08);
SpriteList_Update(v1->unk_08->spriteManager.spriteList);
break;
case 5:
v1->unk_00 = sub_0206F514(v1->unk_08);
SpriteList_Update(v1->unk_08->spriteManager.spriteList);
break;
case 6:
v1->unk_00 = sub_0206F554(v1->unk_08);
SpriteList_Update(v1->unk_08->spriteManager.spriteList);
break;
case 7:
v1->unk_00 = sub_0206F658(v1->unk_08);
SpriteList_Update(v1->unk_08->spriteManager.spriteList);
break;
case 8:
v1->unk_00 = sub_0206F748(v2);
SpriteList_Update(v1->unk_08->spriteManager.spriteList);
break;
case 9:
if (!(gSystem.pressedKeys & PAD_BUTTON_A)) {
return 0;
}
v1->unk_00 = 10;
break;
case 10:
v1->unk_00 = sub_0206F468(v1->unk_08);
break;
case 11:
v1->unk_00 = sub_0206F3A0(v1);
break;
case 12:
Heap_Free(v1);
return 1;
}
return 0;
}
void sub_020703FC(FieldTask *param0, u16 param1)
{
FieldSystem *fieldSystem = FieldTask_GetFieldSystem(param0);
UnkStruct_0206F314 *v1 = Heap_Alloc(HEAP_ID_FIELD2, sizeof(UnkStruct_0206F314));
v1->unk_00 = 0;
v1->unk_04 = param1;
v1->unk_08 = NULL;
FieldTask_InitCall(fieldSystem->task, sub_020702D0, v1);
}

View File

@ -1596,7 +1596,7 @@ void sub_02094C44(UnkStruct_02095C48 *param0, SaveData *saveData, u32 param2, Jo
sub_0206CF14(broadcast, param0->unk_1974, param0->unk_00.contestType, param0->unk_00.contestRank, param0->unk_00.unk_118[param0->unk_00.unk_113].unk_08 + 1);
GameRecords *v5 = SaveData_GetGameRecords(param0->saveData);
GameRecords_IncrementRecordValue(v5, RECORD_UNK_090);
GameRecords_IncrementRecordValue(v5, RECORD_SUPER_CONTEST_PARTICIPATIONS);
if (sub_02094790(param0) == 0) {
GameRecords_IncrementRecordValue(v5, RECORD_SUPER_CONTEST_WINS);
@ -1604,7 +1604,7 @@ void sub_02094C44(UnkStruct_02095C48 *param0, SaveData *saveData, u32 param2, Jo
}
if (v0 == 1) {
GameRecords_IncrementRecordValue(v5, RECORD_UNK_094);
GameRecords_IncrementRecordValue(v5, RECORD_RIBBONS_WON);
}
int i;
@ -1617,7 +1617,7 @@ void sub_02094C44(UnkStruct_02095C48 *param0, SaveData *saveData, u32 param2, Jo
LinkContestRecords_IncrementSavaData(param0->saveData, param0->unk_00.contestType, param0->unk_00.unk_118[param0->unk_00.unk_113].unk_08);
GameRecords *records = SaveData_GetGameRecords(param0->saveData);
GameRecords_IncrementRecordValue(records, RECORD_UNK_091);
GameRecords_IncrementRecordValue(records, RECORD_LINK_CONTEST_PARTICIPATIONS);
if (sub_02094790(param0) == 0) {
GameRecords_IncrementRecordValue(records, RECORD_LINK_CONTEST_WINS);