diff options
author | YamaArashi <shadow962@live.com> | 2016-12-04 03:19:36 -0800 |
---|---|---|
committer | YamaArashi <shadow962@live.com> | 2016-12-04 03:19:36 -0800 |
commit | ffdc442444897fcc0d65301d8630c504e80d4c6f (patch) | |
tree | 0e0bdea9be68bf0733516883204e03a76e71a2ee /src | |
parent | d4247e6eed345be79a0ca4d27dd598d4619be94f (diff) | |
parent | 95ee1e7188948931d49fdcff23ecb29cafc527e5 (diff) |
Merge branch 'marijnvdwerf-trainer-card'
Diffstat (limited to 'src')
-rw-r--r-- | src/new_game.c | 2 | ||||
-rw-r--r-- | src/rom4.c | 8 | ||||
-rw-r--r-- | src/start_menu.c | 1 | ||||
-rw-r--r-- | src/trainer_card.c | 335 |
4 files changed, 337 insertions, 9 deletions
diff --git a/src/new_game.c b/src/new_game.c index c8221fa5d..c36337409 100644 --- a/src/new_game.c +++ b/src/new_game.c @@ -67,7 +67,7 @@ void sub_8052DA8(void) void sub_8052DE4(void) { - CpuFill32(0, gSaveBlock2.filler_A8, sizeof(gSaveBlock2.filler_A8)); + CpuFill32(0, &gSaveBlock2.filler_A8, sizeof(gSaveBlock2.filler_A8)); } void sub_8052E04(void) diff --git a/src/rom4.c b/src/rom4.c index 8b1aa1b4d..ce6bc2e0b 100644 --- a/src/rom4.c +++ b/src/rom4.c @@ -42,14 +42,6 @@ struct UnkTVStruct u32 tv_field_4; }; -struct LinkPlayerMapObject -{ - u8 active; - u8 linkPlayerId; - u8 mapObjId; - u8 mode; -}; - struct UCoords32 { u32 x, y; diff --git a/src/start_menu.c b/src/start_menu.c index 3cffae111..06eb28909 100644 --- a/src/start_menu.c +++ b/src/start_menu.c @@ -11,6 +11,7 @@ #include "sprite.h" #include "string_util.h" #include "task.h" +#include "trainer_card.h" #include "flag.h" #include "rom4.h" #include "safari_zone.h" diff --git a/src/trainer_card.c b/src/trainer_card.c new file mode 100644 index 000000000..84f2d561f --- /dev/null +++ b/src/trainer_card.c @@ -0,0 +1,335 @@ +#include "global.h" +#include "trainer_card.h" +#include "asm.h" +#include "flag.h" +#include "flags.h" +#include "link.h" +#include "main.h" +#include "menu.h" +#include "palette.h" +#include "pokedex.h" +#include "rom4.h" +#include "save_menu_util.h" +#include "sprite.h" +#include "task.h" + +typedef void (*Callback)(void); + +struct Struct2000000 +{ + /*0x00*/ u8 filer0[1]; + /*0x01*/ bool8 var_1; + /*0x02*/ u8 filer1[2]; + /*0x04*/ u8 var_4; + /*0x05*/ u8 var_5; + /*0x06*/ u8 var_6; + /*0x07*/ u8 filler2[0x59]; + /*0x60*/ Callback * var_60; + /*0x64*/ struct TrainerCard var_64; + /*0x9C*/ u8 language; // 0x9C +}; + +extern struct Struct2000000 unk_2000000; +extern struct LinkPlayerMapObject gLinkPlayerMapObjects[]; +extern struct TrainerCard gTrainerCards[4]; + +enum { + TD_0, + TD_1, + TD_CALLBACK, +}; + +static void sub_8093174(void); +static void sub_809323C(void); +static void sub_8093254(void); +static void sub_80932AC(Callback callBack); +static void sub_80932E4(u8 arg1, Callback callBack); +static void nullsub_60(u8); +static u32 sav12_xor_get_clamped_above(u8 index, u32 maxVal); +static u8 sub_80934F4(struct TrainerCard *); +static void sub_8093534(void); +static void sub_8093550(void); + +void sub_8093110(Callback arg1) { + sub_80932AC(arg1); + SetMainCallback2(sub_8093174); + unk_2000000.language = 2; +} + +void sub_8093130(u8 playerIndex, Callback arg2) { + struct Struct2000000* r2; + struct LinkPlayer* r3; + struct LinkPlayerMapObject* r4; + u8 linkPlayerId; + + sub_80932E4(playerIndex, arg2); + SetMainCallback2(sub_8093174); + + r2 = &unk_2000000; + r3 = gLinkPlayers; + r4 = gLinkPlayerMapObjects; + + linkPlayerId = r4[playerIndex].linkPlayerId; + + r2->language = r3[linkPlayerId].language; +} + + +static void sub_8093174(void) { + switch (gMain.state) { + case 0: + sub_8093534(); + sub_8093688(); + gMain.state += 1; + break; + case 1: + sub_8093598(); + gMain.state += 1; + break; + case 2: + sub_80935EC(); + gMain.state += 1; + break; + case 3: + sub_8093610(); + sub_80937A4(); + gMain.state += 1; + break; + case 4: + sub_80937BC(); + gMain.state += 1; + case 5: + if (MultistepInitMenuWindowContinue() == FALSE) { + return; + } + gMain.state += 1; + break; + case 6: + sub_80937F0(); + gMain.state += 1; + break; + case 7: + sub_80937D8(); + gMain.state += 1; + break; + case 8: + nullsub_15(); + sub_8093800(); + sub_8093550(); + SetMainCallback2(sub_809323C); + break; + } +} + +static void sub_809323C(void) { + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +__attribute__((naked)) +static void sub_8093254(void) +{ + asm(".syntax unified\n\ + push {lr}\n\ + bl LoadOam\n\ + bl ProcessSpriteCopyRequests\n\ + bl TransferPlttBuffer\n\ + ldr r2, _0809329C @ =0x02000000\n\ + ldrb r0, [r2, 0x6]\n\ + adds r0, 0x1\n\ + strb r0, [r2, 0x6]\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x3B\n\ + bls _0809327E\n\ + movs r0, 0\n\ + strb r0, [r2, 0x6]\n\ + ldrb r0, [r2, 0x5]\n\ + movs r1, 0x1\n\ + eors r0, r1\n\ + strb r0, [r2, 0x5]\n\ +_0809327E:\n\ + ldrb r0, [r2, 0x4]\n\ + cmp r0, 0\n\ + beq _08093298\n\ + ldr r1, _080932A0 @ =0x040000d4\n\ + ldr r0, _080932A4 @ =gUnknown_03004DE0\n\ + str r0, [r1]\n\ + movs r2, 0xF0\n\ + lsls r2, 3\n\ + adds r0, r2\n\ + str r0, [r1, 0x4]\n\ + ldr r0, _080932A8 @ =0x800000a0\n\ + str r0, [r1, 0x8]\n\ + ldr r0, [r1, 0x8]\n\ +_08093298:\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_0809329C: .4byte 0x02000000\n\ +_080932A0: .4byte 0x040000d4\n\ +_080932A4: .4byte gUnknown_03004DE0\n\ +_080932A8: .4byte 0x800000a0\n\ + .syntax divided\n"); +} + +static void sub_80932AC(Callback callBack) { + u8 taskId = CreateTask(nullsub_60, 0xFF); + struct Task *task = &gTasks[taskId]; + task->data[TD_0] = FALSE; + StoreWordInTwoHalfwords(&task->data[TD_CALLBACK], (u32) callBack); +} + +static void sub_80932E4(u8 arg1, Callback callBack) { + u8 taskId = CreateTask(nullsub_60, 0xFF); + + struct Task *task = &gTasks[taskId]; + task->data[TD_0] = TRUE; + task->data[TD_1] = arg1; + StoreWordInTwoHalfwords(&task->data[TD_CALLBACK], (u32) callBack); +} + +void sub_8093324(void) { + u8 taskId = FindTaskIdByFunc(nullsub_60); + struct Task *task = &gTasks[taskId]; + unk_2000000.var_1 = task->data[TD_0]; + + LoadWordFromTwoHalfwords((u16 *) &task->data[TD_CALLBACK], (u32 *) &unk_2000000.var_60); + + if (unk_2000000.var_1) { + struct TrainerCard (*trainerCards)[4] = &gTrainerCards; + s16 var = task->data[TD_1]; + struct TrainerCard *dest = &(*trainerCards)[var]; + memcpy(&unk_2000000.var_64, dest, sizeof(struct TrainerCard)); + } else { + sub_8093390(&unk_2000000.var_64); + } +} + +static void nullsub_60(u8 taskid) { +} + +void sub_8093390(struct TrainerCard *arg1) { + u32 playTime; + bool32 enteredHallOfFame; + bool8 r4; + u8 i; + + arg1->gender = gSaveBlock2.playerGender; + arg1->playTimeHours = gSaveBlock2.playTimeHours; + arg1->playTimeMinutes = gSaveBlock2.playTimeMinutes; + + playTime = sub_8053108(GAME_STAT_FIRST_HOF_PLAY_TIME); + enteredHallOfFame = sub_8053108(GAME_STAT_ENTERED_HOF); + if (!enteredHallOfFame) { + playTime = 0; + } + arg1->firstHallOfFameA = playTime >> 16; + arg1->firstHallOfFameB = (playTime >> 8) & 0xFF; + arg1->firstHallOfFameC = playTime & 0xFF; + + arg1->hasPokedex = FlagGet(SYS_POKEDEX_GET); + arg1->var_3 = sub_8090FC0(); + arg1->pokedexSeen = GetPokedexSeenCount(); + + arg1->trainerId = (gSaveBlock2.playerTrainerId[1] << 8) | gSaveBlock2.playerTrainerId[0]; + + // Link Cable Battles + arg1->linkBattleWins = sav12_xor_get_clamped_above(GAME_STAT_LINK_BATTLE_WINS, 9999); + arg1->linkBattleLosses = sav12_xor_get_clamped_above(GAME_STAT_LINK_BATTLE_LOSSES, 9999); + + // Contests w/ Friends + arg1->contestsWithFriends = sav12_xor_get_clamped_above(GAME_STAT_WON_LINK_CONTEST, 999); + + // Pokéblocks w/ Friends + arg1->pokeblocksWithFriends = sav12_xor_get_clamped_above(GAME_STAT_POKEBLOCKS_WITH_FRIENDS, 0xFFFF); + + // Pokémon Trades + arg1->pokemonTrades = sav12_xor_get_clamped_above(GAME_STAT_POKEMON_TRADES, 0xFFFF); + + // Battle tower? + arg1->var_18 = gSaveBlock2.filler_A8.var_4C8; + arg1->var_1A = gSaveBlock2.filler_A8.var_4CA; + if (arg1->var_18 > 9999) { + arg1->var_18 = 9999; + } + if (arg1->var_1A > 9999) { + arg1->var_1A = 9999; + } + + r4 = FALSE; + if (sub_80C4D50() > 4) { + r4 = TRUE; + } + arg1->var_4 = r4; + + arg1->money = gSaveBlock1.money; + + for (i = 0; i < 4; i++) { + arg1->var_28[i] = gSaveBlock1.unk2B1C[i]; + } + + for (i = 0; i < 8; i++) { + arg1->playerName[i] = gSaveBlock2.playerName[i]; + } + + arg1->var_1 = sub_80934F4(arg1); +} + +u8 sub_80934C4(u8 id) { + return gTrainerCards[id].var_1; +} + +static u32 sav12_xor_get_clamped_above(u8 index, u32 maxVal) { + u32 value = sub_8053108(index); + + if (value > maxVal) { + value = maxVal; + } + + return value; +} + +static u8 sub_80934F4(struct TrainerCard *trainerCard) { + u8 value = 0; + + if (trainerCard->firstHallOfFameA != 0 || trainerCard->firstHallOfFameB != 0 || trainerCard->firstHallOfFameC != 0) { + value += 1; + } + + if (trainerCard->var_3) { + value += 1; + } + + if (trainerCard->var_1A > 49) { + value += 1; + } + + if (trainerCard->var_4) { + value += 1; + } + + return value; +} + +static void sub_8093534(void) { + SetVBlankCallback(NULL); + SetHBlankCallback(NULL); + REG_DISPCNT = 0; +} + +static void sub_8093550(void) { + u16 backup; + + SetVBlankCallback(sub_8093254); + + backup = REG_IME; + REG_IME = 0; + REG_IE |= INTR_FLAG_VBLANK| INTR_FLAG_HBLANK; + REG_IME = backup; + + REG_DISPSTAT |= DISPSTAT_VBLANK_INTR | DISPSTAT_HBLANK_INTR; + REG_DISPCNT = 0x1f40; +} |