Merge pull request #242 from DizzyEggg/decompile_battle_records

Decompile battle records
This commit is contained in:
Marcus Huderle
2018-05-03 08:42:44 -07:00
committed by GitHub
32 changed files with 659 additions and 1423 deletions
+510
View File
@@ -0,0 +1,510 @@
#include "global.h"
#include "battle_records.h"
#include "bg.h"
#include "window.h"
#include "link.h"
#include "battle.h"
#include "overworld.h"
#include "text.h"
#include "text_window.h"
#include "strings.h"
#include "string_util.h"
#include "trainer_card.h"
#include "menu.h"
#include "menu_helpers.h"
#include "palette.h"
#include "main.h"
#include "scanline_effect.h"
#include "international_string_util.h"
#include "sound.h"
#include "constants/songs.h"
#include "malloc.h"
#include "gpu_regs.h"
#include "constants/game_stat.h"
extern void PrintOnTrainerHillRecordsWindow(void); // pokenav.s
// this file's functions
static void Task_CloseTrainerHillRecordsOnButton(u8 taskId);
static void Task_BeginPaletteFade(u8 taskId);
static void Task_ExitTrainerHillRecords(u8 taskId);
static void RemoveTrainerHillRecordsWindow(u8 windowId);
static void CB2_ShowTrainerHillRecords(void);
// EWRAM variables
EWRAM_DATA u8 gRecordsWindowId = 0;
EWRAM_DATA static u8 *sTilemapBuffer = NULL;
// const rom data
static const u32 sTrainerHillWindowTileset[] = INCBIN_U32("graphics/unknown/unknown_5B3484.4bpp");
static const u16 sTrainerHillWindowPalette[] = INCBIN_U16("graphics/unknown/unknown_5B3484.gbapal");
static const u32 sTrainerHillWindowTilemap[] = INCBIN_U32("graphics/unknown/unknown_5B3564.bin");
static const struct BgTemplate sTrainerHillRecordsBgTemplates[] =
{
{
.bg = 0,
.charBaseIndex = 0,
.mapBaseIndex = 31,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0
},
{
.bg = 3,
.charBaseIndex = 1,
.mapBaseIndex = 30,
.screenSize = 0,
.paletteMode = 0,
.priority = 3,
.baseTile = 0
}
};
static const struct WindowTemplate sTrainerHillRecordsWindowTemplates[] =
{
{0x0, 0x2, 0x1, 0x1A, 0x12, 0xF, 0x14},
DUMMY_WIN_TEMPLATE
};
static const struct WindowTemplate sLinkBattleRecordsWindow = {0x0, 0x2, 0x1, 0x1A, 0x11, 0xF, 0x1};
static const u8 sText_DashesNoPlayer[] = _("-------");
static const u8 sText_DashesNoScore[] = _("----");
// code
static void ClearLinkBattleRecord(struct LinkBattleRecord *record)
{
CpuFill16(0, record, sizeof(struct LinkBattleRecord));
record->name[0] = EOS;
record->trainerId = 0;
record->wins = 0;
record->losses = 0;
record->draws = 0;
}
static void ClearLinkBattleRecords(struct LinkBattleRecord *records)
{
s32 i;
for (i = 0; i < LINK_B_RECORDS_COUNT; i++)
{
ClearLinkBattleRecord(records + i);
}
SetGameStat(GAME_STAT_LINK_BATTLE_WINS, 0);
SetGameStat(GAME_STAT_LINK_BATTLE_LOSSES, 0);
SetGameStat(GAME_STAT_LINK_BATTLE_DRAWS, 0);
}
static s32 GetLinkBattleRecordTotalBattles(struct LinkBattleRecord *record)
{
return record->wins + record->losses + record->draws;
}
static s32 FindLinkBattleRecord(struct LinkBattleRecord *records, const u8 *name, u16 trainerId)
{
s32 i;
for (i = 0; i < LINK_B_RECORDS_COUNT; i++)
{
if (!StringCompareN(records[i].name, name, OT_NAME_LENGTH) && records[i].trainerId == trainerId)
return i;
}
return LINK_B_RECORDS_COUNT;
}
static void SortLinkBattleRecords(struct LinkBattleRecords *records)
{
s32 i, j;
for (i = LINK_B_RECORDS_COUNT - 1; i > 0; i--)
{
for (j = i - 1; j >= 0; j--)
{
s32 totalBattlesI = GetLinkBattleRecordTotalBattles(&records->entries[i]);
s32 totalBattlesJ = GetLinkBattleRecordTotalBattles(&records->entries[j]);
if (totalBattlesI > totalBattlesJ)
{
struct LinkBattleRecord temp1;
u8 temp2;
temp1 = records->entries[i];
records->entries[i] = records->entries[j];
records->entries[j] = temp1;
temp2 = records->languages[i];
records->languages[i] = records->languages[j];
records->languages[j] = temp2;
}
}
}
}
static void UpdateLinkBattleRecord(struct LinkBattleRecord *record, s32 battleOutcome)
{
switch (battleOutcome)
{
case B_OUTCOME_WON:
record->wins++;
if (record->wins > 9999)
record->wins = 9999;
break;
case B_OUTCOME_LOST:
record->losses++;
if (record->losses > 9999)
record->losses = 9999;
break;
case B_OUTCOME_DREW:
record->draws++;
if (record->draws > 9999)
record->draws = 9999;
break;
}
}
static void UpdateLinkBattleGameStats(s32 battleOutcome)
{
u8 stat;
switch (battleOutcome)
{
case B_OUTCOME_WON:
stat = GAME_STAT_LINK_BATTLE_WINS;
break;
case B_OUTCOME_LOST:
stat = GAME_STAT_LINK_BATTLE_LOSSES;
break;
case B_OUTCOME_DREW:
stat = GAME_STAT_LINK_BATTLE_DRAWS;
break;
default:
return;
}
if (GetGameStat(stat) < 9999)
IncrementGameStat(stat);
}
static void UpdateLinkBattleRecords(struct LinkBattleRecords *records, const u8 *name, u16 trainerId, s32 battleOutcome, u8 battlerId)
{
s32 index;
UpdateLinkBattleGameStats(battleOutcome);
SortLinkBattleRecords(records);
index = FindLinkBattleRecord(records->entries, name, trainerId);
if (index == LINK_B_RECORDS_COUNT)
{
index = LINK_B_RECORDS_COUNT - 1;
ClearLinkBattleRecord(&records->entries[index]);
StringCopyN(records->entries[index].name, name, OT_NAME_LENGTH);
records->entries[index].trainerId = trainerId;
records->languages[index] = gLinkPlayers[battlerId].language;
}
UpdateLinkBattleRecord(&records->entries[index], battleOutcome);
SortLinkBattleRecords(records);
}
void ClearPlayerLinkBattleRecords(void)
{
ClearLinkBattleRecords(gSaveBlock1Ptr->linkBattleRecords.entries);
}
static void IncTrainerCardWins(s32 battlerId)
{
u16 *wins = &gTrainerCards[battlerId].linkBattleWins;
(*wins)++;
if (*wins > 9999)
*wins = 9999;
}
static void IncTrainerCardLosses(s32 battlerId)
{
u16 *losses = &gTrainerCards[battlerId].linkBattleLosses;
(*losses)++;
if (*losses > 9999)
*losses = 9999;
}
static void UpdateTrainerCardWinsLosses(s32 battlerId)
{
switch (gBattleOutcome)
{
case B_OUTCOME_WON:
IncTrainerCardWins(BATTLE_OPPOSITE(battlerId));
IncTrainerCardLosses(battlerId);
break;
case B_OUTCOME_LOST:
IncTrainerCardLosses(BATTLE_OPPOSITE(battlerId));
IncTrainerCardWins(battlerId);
break;
}
}
void UpdatePlayerLinkBattleRecords(s32 battlerId)
{
if (InUnionRoom() != TRUE)
{
UpdateTrainerCardWinsLosses(battlerId);
UpdateLinkBattleRecords(
&gSaveBlock1Ptr->linkBattleRecords,
gTrainerCards[battlerId].playerName,
gTrainerCards[battlerId].trainerId,
gBattleOutcome,
battlerId);
}
}
static void PrintLinkBattleWinsLossesDraws(struct LinkBattleRecord *records)
{
s32 x;
ConvertIntToDecimalStringN(gStringVar1, GetGameStat(GAME_STAT_LINK_BATTLE_WINS), STR_CONV_MODE_LEFT_ALIGN, 4);
ConvertIntToDecimalStringN(gStringVar2, GetGameStat(GAME_STAT_LINK_BATTLE_LOSSES), STR_CONV_MODE_LEFT_ALIGN, 4);
ConvertIntToDecimalStringN(gStringVar3, GetGameStat(GAME_STAT_LINK_BATTLE_DRAWS), STR_CONV_MODE_LEFT_ALIGN, 4);
StringExpandPlaceholders(gStringVar4, gText_TotalRecordWLD);
x = GetStringCenterAlignXOffset(1, gStringVar4, 0xD0);
PrintTextOnWindow(gRecordsWindowId, 1, gStringVar4, x, 0x11, 0, NULL);
}
static void PrintLinkBattleRecord(struct LinkBattleRecord *record, u8 y, s32 language)
{
if (record->wins == 0 && record->losses == 0 && record->draws == 0)
{
// empty slot
PrintTextOnWindow(gRecordsWindowId, 1, sText_DashesNoPlayer, 8, (y * 8) + 1, 0, NULL);
PrintTextOnWindow(gRecordsWindowId, 1, sText_DashesNoScore, 80, (y * 8) + 1, 0, NULL);
PrintTextOnWindow(gRecordsWindowId, 1, sText_DashesNoScore, 128, (y * 8) + 1, 0, NULL);
PrintTextOnWindow(gRecordsWindowId, 1, sText_DashesNoScore, 176, (y * 8) + 1, 0, NULL);
}
else
{
StringFillWithTerminator(gStringVar1, 8);
StringCopyN(gStringVar1, record->name, 7);
ConvertInternationalString(gStringVar1, language);
PrintTextOnWindow(gRecordsWindowId, 1, gStringVar1, 8, (y * 8) + 1, 0, NULL);
ConvertIntToDecimalStringN(gStringVar1, record->wins, STR_CONV_MODE_RIGHT_ALIGN, 4);
PrintTextOnWindow(gRecordsWindowId, 1, gStringVar1, 80, (y * 8) + 1, 0, NULL);
ConvertIntToDecimalStringN(gStringVar1, record->losses, STR_CONV_MODE_RIGHT_ALIGN, 4);
PrintTextOnWindow(gRecordsWindowId, 1, gStringVar1, 128, (y * 8) + 1, 0, NULL);
ConvertIntToDecimalStringN(gStringVar1, record->draws, STR_CONV_MODE_RIGHT_ALIGN, 4);
PrintTextOnWindow(gRecordsWindowId, 1, gStringVar1, 176, (y * 8) + 1, 0, NULL);
}
}
void ShowLinkBattleRecords(void)
{
s32 i, x;
gRecordsWindowId = AddWindow(&sLinkBattleRecordsWindow);
NewMenuHelpers_DrawStdWindowFrame(gRecordsWindowId, FALSE);
FillWindowPixelBuffer(gRecordsWindowId, 0x11);
StringExpandPlaceholders(gStringVar4, gText_PlayersBattleResults);
x = GetStringCenterAlignXOffset(1, gStringVar4, 208);
PrintTextOnWindow(gRecordsWindowId, 1, gStringVar4, x, 1, 0, NULL);
PrintLinkBattleWinsLossesDraws(gSaveBlock1Ptr->linkBattleRecords.entries);
StringExpandPlaceholders(gStringVar4, gText_WinLoseDraw);
PrintTextOnWindow(gRecordsWindowId, 1, gStringVar4, 0, 41, 0, NULL);
for (i = 0; i < LINK_B_RECORDS_COUNT; i++)
{
PrintLinkBattleRecord(&gSaveBlock1Ptr->linkBattleRecords.entries[i], 7 + (i * 2), gSaveBlock1Ptr->linkBattleRecords.languages[i]);
}
PutWindowTilemap(gRecordsWindowId);
CopyWindowToVram(gRecordsWindowId, 3);
}
void RemoveRecordsWindow(void)
{
sub_819746C(gRecordsWindowId, FALSE);
RemoveWindow(gRecordsWindowId);
}
static void Task_TrainerHillWaitForPaletteFade(u8 taskId)
{
if (!gPaletteFade.active)
gTasks[taskId].func = Task_CloseTrainerHillRecordsOnButton;
}
static void Task_CloseTrainerHillRecordsOnButton(u8 taskId)
{
struct Task *task = &gTasks[taskId];
if (gMain.newKeys & A_BUTTON || gMain.newKeys & B_BUTTON)
{
PlaySE(SE_SELECT);
task->func = Task_BeginPaletteFade;
}
}
static void Task_BeginPaletteFade(u8 taskId)
{
BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
gTasks[taskId].func = Task_ExitTrainerHillRecords;
}
static void Task_ExitTrainerHillRecords(u8 taskId)
{
if (!gPaletteFade.active)
{
SetMainCallback2(CB2_ReturnToFieldContinueScript);
Free(sTilemapBuffer);
RemoveTrainerHillRecordsWindow(0);
FreeAllWindowBuffers();
DestroyTask(taskId);
}
}
static void RemoveTrainerHillRecordsWindow(u8 windowId)
{
FillWindowPixelBuffer(windowId, 0);
ClearWindowTilemap(windowId);
CopyWindowToVram(windowId, 2);
RemoveWindow(windowId);
}
static void ClearVramOamPlttRegs(void)
{
DmaClearLarge16(3, (void*)(VRAM), VRAM_SIZE, 0x1000);
DmaClear32(3, OAM, OAM_SIZE);
DmaClear16(3, PLTT, PLTT_SIZE);
SetGpuReg(REG_OFFSET_DISPCNT, 0);
SetGpuReg(REG_OFFSET_BG0CNT, 0);
SetGpuReg(REG_OFFSET_BG0HOFS, 0);
SetGpuReg(REG_OFFSET_BG0VOFS, 0);
SetGpuReg(REG_OFFSET_BG1CNT, 0);
SetGpuReg(REG_OFFSET_BG1HOFS, 0);
SetGpuReg(REG_OFFSET_BG1VOFS, 0);
SetGpuReg(REG_OFFSET_BG2CNT, 0);
SetGpuReg(REG_OFFSET_BG2HOFS, 0);
SetGpuReg(REG_OFFSET_BG2VOFS, 0);
SetGpuReg(REG_OFFSET_BG3CNT, 0);
SetGpuReg(REG_OFFSET_BG3HOFS, 0);
SetGpuReg(REG_OFFSET_BG3VOFS, 0);
SetGpuReg(REG_OFFSET_WIN0H, 0);
SetGpuReg(REG_OFFSET_WIN0V, 0);
SetGpuReg(REG_OFFSET_WININ, 0);
SetGpuReg(REG_OFFSET_WINOUT, 0);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetGpuReg(REG_OFFSET_BLDY, 0);
}
static void ClearTasksAndGraphicalStructs(void)
{
ScanlineEffect_Stop();
ResetTasks();
ResetSpriteData();
ResetPaletteFade();
FreeAllSpritePalettes();
}
static void ResetBgCoordinates(void)
{
ChangeBgX(0, 0, 0);
ChangeBgY(0, 0, 0);
ChangeBgX(1, 0, 0);
ChangeBgY(1, 0, 0);
ChangeBgX(2, 0, 0);
ChangeBgY(2, 0, 0);
ChangeBgX(3, 0, 0);
ChangeBgY(3, 0, 0);
}
static void SetDispcntReg(void)
{
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_BG0_ON | DISPCNT_BG3_ON | DISPCNT_OBJ_1D_MAP);
}
static void LoadTrainerHillRecordsWindowGfx(u8 bgId)
{
LoadBgTiles(bgId, sTrainerHillWindowTileset, sizeof(sTrainerHillWindowTileset), 0);
CopyToBgTilemapBufferRect(bgId, sTrainerHillWindowTilemap, 0, 0, 0x20, 0x20);
LoadPalette(sTrainerHillWindowPalette, 0, 0x20);
}
static void VblankCB_TrainerHillRecords(void)
{
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
}
static void MainCB2_TrainerHillRecords(void)
{
RunTasks();
AnimateSprites();
BuildOamBuffer();
UpdatePaletteFade();
}
void ShowTrainerHillRecords(void)
{
SetVBlankCallback(NULL);
SetMainCallback2(CB2_ShowTrainerHillRecords);
}
static void CB2_ShowTrainerHillRecords(void)
{
switch (gMain.state)
{
case 0:
SetVBlankCallback(NULL);
ClearVramOamPlttRegs();
gMain.state++;
break;
case 1:
ClearTasksAndGraphicalStructs();
gMain.state++;
break;
case 2:
sTilemapBuffer = AllocZeroed(0x800);
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, sTrainerHillRecordsBgTemplates, ARRAY_COUNT(sTrainerHillRecordsBgTemplates));
SetBgTilemapBuffer(3, sTilemapBuffer);
ResetBgCoordinates();
gMain.state++;
break;
case 3:
LoadTrainerHillRecordsWindowGfx(3);
LoadPalette(stdpal_get(0), 0xF0, 0x20);
gMain.state++;
break;
case 4:
if (IsDma3ManagerBusyWithBgCopy() != TRUE)
{
ShowBg(0);
ShowBg(3);
CopyBgTilemapBufferToVram(3);
gMain.state++;
}
break;
case 5:
InitWindows(sTrainerHillRecordsWindowTemplates);
DeactivateAllTextPrinters();
gMain.state++;
break;
case 6:
BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
gMain.state++;
break;
case 7:
SetDispcntReg();
SetVBlankCallback(VblankCB_TrainerHillRecords);
PrintOnTrainerHillRecordsWindow();
CreateTask(Task_TrainerHillWaitForPaletteFade, 8);
SetMainCallback2(MainCB2_TrainerHillRecords);
gMain.state = 0;
break;
}
}
+9 -9
View File
@@ -30,6 +30,7 @@
#include "trig.h"
#include "tv.h"
#include "item_menu.h"
#include "battle_records.h"
#define BLENDER_SCORE_BEST 0
#define BLENDER_SCORE_GOOD 1
@@ -131,7 +132,6 @@ extern struct MusicPlayerInfo gMPlayInfo_SE2;
extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern u8 gInGameOpponentsNo;
extern u8 gUnknown_020322D5;
extern u8 gResultsWindowId;
// graphics
extern const u8 gBerryBlenderArrowTiles[];
@@ -3485,13 +3485,13 @@ void ShowBerryBlenderRecordWindow(void)
u8 text[32];
winTemplate = sBlenderRecordWindowTemplate;
gResultsWindowId = AddWindow(&winTemplate);
NewMenuHelpers_DrawStdWindowFrame(gResultsWindowId, 0);
FillWindowPixelBuffer(gResultsWindowId, 0x11);
gRecordsWindowId = AddWindow(&winTemplate);
NewMenuHelpers_DrawStdWindowFrame(gRecordsWindowId, 0);
FillWindowPixelBuffer(gRecordsWindowId, 0x11);
xPos = GetStringCenterAlignXOffset(1, gText_BlenderMaxSpeedRecord, 0x90);
PrintTextOnWindow(gResultsWindowId, 1, gText_BlenderMaxSpeedRecord, xPos, 1, 0, NULL);
PrintTextOnWindow(gResultsWindowId, 1, gText_234Players, 4, 0x29, 0, NULL);
PrintTextOnWindow(gRecordsWindowId, 1, gText_BlenderMaxSpeedRecord, xPos, 1, 0, NULL);
PrintTextOnWindow(gRecordsWindowId, 1, gText_234Players, 4, 0x29, 0, NULL);
for (i = 0, yPos = 0x29; i < BLENDER_SCORES_NO; i++)
{
@@ -3506,11 +3506,11 @@ void ShowBerryBlenderRecordWindow(void)
txtPtr = StringAppend(txtPtr, sText_RPM);
xPos = GetStringRightAlignXOffset(1, text, 0x8C);
PrintTextOnWindow(gResultsWindowId, 1, text, xPos, yPos + (i * 16), 0, NULL);
PrintTextOnWindow(gRecordsWindowId, 1, text, xPos, yPos + (i * 16), 0, NULL);
}
PutWindowTilemap(gResultsWindowId);
CopyWindowToVram(gResultsWindowId, 3);
PutWindowTilemap(gRecordsWindowId);
CopyWindowToVram(gRecordsWindowId, 3);
}
static void sub_8083F3C(u8 taskId)
+2 -2
View File
@@ -965,9 +965,9 @@ void CopyBgTilemapBufferToVram(u8 bg)
}
}
void CopyToBgTilemapBufferRect(u8 bg, void* src, u8 destX, u8 destY, u8 width, u8 height)
void CopyToBgTilemapBufferRect(u8 bg, const void* src, u8 destX, u8 destY, u8 width, u8 height)
{
void* srcCopy;
const void* srcCopy;
u16 destX16;
u16 destY16;
u16 mode;
+5 -7
View File
@@ -20,8 +20,10 @@
#include "tv.h"
#include "coins.h"
#include "text.h"
#include "overworld.h"
#include "mail.h"
#include "battle_records.h"
extern u8 gPlayerPartyCount;
extern u8 gDifferentSaveFile;
extern u16 gSaveFileStatus;
extern u8 gUnknown_030060B0;
@@ -29,19 +31,15 @@ extern u8 gUnknown_030060B0;
// TODO: replace those declarations with file headers
extern u16 GetGeneratedTrainerIdLower(void);
extern void ClearContestWinnerPicsInContestHall(void);
extern void Overworld_SetWarpDestination(s8 mapBank, s8 mapNo, s8 warpNo, s8 xPos, s8 yPos);
extern void warp_in(void);
extern void sub_80BB358(void);
extern void ResetBagScrollPositions(void);
extern void ResetPokedex(void);
extern void sub_8084400(void);
extern void ClearMailData(void);
extern void ResetGabbyAndTy(void);
extern void ResetSecretBases(void);
extern void ResetLinkContestBoolean(void);
extern void ResetGameStats(void);
extern void sub_8052DA8(void);
extern void InitLinkBattleRecords(void);
extern void ResetPokemonStorageSystem(void);
extern void ClearBag(void);
extern void NewGameInitPCItems(void);
@@ -58,7 +56,7 @@ extern void ResetContestLinkResults(void);
extern void ResetPokeJumpResults(void);
extern void SetBerryPowder(u32* powder, u32 newValue);
extern u8 EventScript_2715DE[];
extern const u8 EventScript_2715DE[];
void WriteUnalignedWord(u32 var, u8 *dataPtr)
{
@@ -178,7 +176,7 @@ void NewGameInitData(void)
ResetLinkContestBoolean();
ResetGameStats();
ClearAllContestWinnerPics();
InitLinkBattleRecords();
ClearPlayerLinkBattleRecords();
InitSeedotSizeRecord();
InitLotadSizeRecord();
gPlayerPartyCount = 0;
+3 -3
View File
@@ -1380,13 +1380,13 @@ void PutFanClubSpecialOnTheAir(void)
StringCopy(show->fanClubSpecial.idolName, name);
tv_store_id_2x(show);
show->fanClubSpecial.language = gGameLanguage;
if (show->fanClubSpecial.language == LANGUAGE_JAPANESE || gSaveBlock1Ptr->unk_31A0 == LANGUAGE_JAPANESE)
if (show->fanClubSpecial.language == LANGUAGE_JAPANESE || gSaveBlock1Ptr->linkBattleRecords.languages[0] == LANGUAGE_JAPANESE)
{
show->fanClubSpecial.idolNameLanguage = LANGUAGE_JAPANESE;
}
else
{
show->fanClubSpecial.idolNameLanguage = gSaveBlock1Ptr->unk_31A0;
show->fanClubSpecial.idolNameLanguage = gSaveBlock1Ptr->linkBattleRecords.languages[0];
}
}
@@ -2465,7 +2465,7 @@ bool8 sub_80EE7C0(void)
{
return TRUE;
}
if (gSaveBlock1Ptr->linkBattleRecords[0].name[0] == EOS)
if (gSaveBlock1Ptr->linkBattleRecords.entries[0].name[0] == EOS)
{
return TRUE;
}