mirror of https://github.com/zeldaret/tmc
1684 lines
41 KiB
C
1684 lines
41 KiB
C
/**
|
|
* @file fileselect.c
|
|
* @ingroup Tasks
|
|
*
|
|
* @brief File select task
|
|
*/
|
|
#include "fileselect.h"
|
|
|
|
#include "common.h"
|
|
#include "figurineMenu.h"
|
|
#include "functions.h"
|
|
#include "game.h"
|
|
#include "item.h"
|
|
#include "kinstone.h"
|
|
#include "main.h"
|
|
#include "menu.h"
|
|
#include "message.h"
|
|
#include "object.h"
|
|
#include "screen.h"
|
|
#include "subtask.h"
|
|
#include "ui.h"
|
|
|
|
// copy, erase, start
|
|
#define NUM_FILE_OPERATIONS 3
|
|
|
|
typedef enum {
|
|
STATE_NONE,
|
|
STATE_NEW,
|
|
STATE_CHOOSE_LANG,
|
|
STATE_OPTIONS,
|
|
STATE_VIEW,
|
|
STATE_COPY,
|
|
STATE_ERASE,
|
|
STATE_START,
|
|
} FileSelectState;
|
|
|
|
// todo: does this belong with gMapDataBottomSpecial?
|
|
typedef enum {
|
|
SAVE_EMPTY = 0,
|
|
SAVE_VALID = 1,
|
|
SAVE_DELETED = 0xFFFFFFFF,
|
|
} SaveStatus;
|
|
|
|
typedef enum {
|
|
RESULT_INVALID = 0,
|
|
RESULT_ASCII = 1,
|
|
} CharResult;
|
|
|
|
const struct_080FC3E4 gUnk_080FC3E4[] = {
|
|
{ 0, 0, 128, 1 },
|
|
{ 0, 0, 0, 1 },
|
|
{ 0, 0, 0, 1 },
|
|
{ 0, 0, 0, 1 },
|
|
{ 0, 0, 0, 1 },
|
|
#ifdef EU
|
|
{ 0, 0, 0, 1 },
|
|
#else
|
|
{ 0, 0, 2, 1 },
|
|
#endif
|
|
{ 0, 0, 0, 1 },
|
|
{ 0, 0, 0, 1 },
|
|
{ 0, 0, 0, 1 },
|
|
{ 0, 0, 0, 1 },
|
|
{ 0, KINSTONE_2C, UNK_6_10, 1 },
|
|
{ 0, 0, 0, 1 },
|
|
{ 0, 0, 0, 1 },
|
|
{ 0, 0, 4, 1 },
|
|
{ 0, 0, 7, 1 },
|
|
{ 0, 0, 3, 1 },
|
|
{ 0, 0, 0, 1 },
|
|
{ 0, 0, 4, 1 },
|
|
#ifdef EU
|
|
{ 0, 0, 2, 1 },
|
|
#else
|
|
{ 0, 0, 3, 1 },
|
|
#endif
|
|
{ 0, 0, 0, 1 },
|
|
{ 0, 0, 0, 1 },
|
|
{ 0, 0, 0, 1 },
|
|
#if defined(EU) || defined(JP)
|
|
{ 0, 0x12, UNK_6_40, 1 },
|
|
#else
|
|
{ 0, 5, UNK_6_20, 1 },
|
|
#endif
|
|
{ 0, 0, 0, 1 },
|
|
{ FLAG_BANK_4, YAMADOUKUTU_0E_SENNIN, UNK_6_40, 1 },
|
|
{ 0, 0, 3, 1 },
|
|
{ 0, 0, 5, 1 },
|
|
{ 0, 0, 5, 1 },
|
|
{ 0, 0, 3, 1 },
|
|
{ 0, 0, 1, 1 },
|
|
{ 0, 0, 3, 1 },
|
|
{ 0, 0, 5, 1 },
|
|
{ 0, 0, 3, 1 },
|
|
{ 0, 0, 2, 1 },
|
|
{ 0, 0, 2, 1 },
|
|
{ 0, 0, 2, 1 },
|
|
{ 0, 0, UNK_6_20, 1 },
|
|
{ 0, KINSTONE_30, UNK_6_10, 1 },
|
|
{ 0, 0, 0, 1 },
|
|
{ 0, 0, 0, 1 },
|
|
{ 0, 0, 0, 1 },
|
|
{ 0, 0, 4, 1 },
|
|
{ 0, 0, 4, 1 },
|
|
{ 0, 0, 3, 1 },
|
|
{ 0, 0, 3, 1 },
|
|
{ FLAG_BANK_4, GORON_DOUKUTU_APPEAR, UNK_6_40, 1 },
|
|
{ 0, 0, 3, 1 },
|
|
{ 0, 0, 3, 0 },
|
|
{ 0, 0, 4, 0 },
|
|
{ 0, 0, 7, 0 },
|
|
{ 0, 0, 0, 0 },
|
|
{ 0, 0, 0, 0 },
|
|
{ 0, 0, 0, 0 },
|
|
{ 0, 0, 2, 0 },
|
|
{ 0, 0, 0, 0 },
|
|
{ 0, 0, 0, 0 },
|
|
{ 0, 0, 4, 0 },
|
|
{ 0, 0, 0, 0 },
|
|
{ 0, 0, 0, 0 },
|
|
{ 0, 0, 4, 0 },
|
|
{ 0, 0, 3, 0 },
|
|
{ 0, 0, 3, 0 },
|
|
{ 0, 0, 6, 0 },
|
|
{ 0, 0, 0, 0 },
|
|
{ 0, 0, 7, 0 },
|
|
#ifdef EU
|
|
{ 0, 0, 0, 0 },
|
|
#else
|
|
{ 0, 0, 2, 0 },
|
|
#endif
|
|
{ 0, KINSTONE_33, UNK_6_10, 1 },
|
|
{ 0, 1, UNK_6_20, 0 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 0, 4, 2 },
|
|
{ 0, 0, 4, 2 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 0, 3, 2 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 0, 3, 2 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 0, 5, 2 },
|
|
{ 0, 0, 7, 2 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 0, 3, 2 },
|
|
{ 0, 0, 3, 3 },
|
|
{ 0, 0, 7, 3 },
|
|
{ 0, 0, 0, 2 },
|
|
#ifdef EU
|
|
{ 0, 0, 3, 2 },
|
|
{ 0, 0, 6, 2 },
|
|
#else
|
|
{ 0, 0, 6, 2 },
|
|
{ 0, 0, 3, 2 },
|
|
#endif
|
|
{ 0, 0, 5, 2 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 0, 4, 2 },
|
|
{ 0, 0, 3, 2 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 0, 7, 2 },
|
|
{ 0, 0, 3, 2 },
|
|
{ 0, 0, 3, 2 },
|
|
{ 0, 0, 3, 2 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 0, 7, 3 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 0, 2, 2 },
|
|
{ 0, 0, 2, 2 },
|
|
{ 0, 0, 6, 2 },
|
|
{ 0, 0, 4, 2 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 0, 3, 2 },
|
|
{ 0, 0, 7, 2 },
|
|
{ 0, 0, 7, 2 },
|
|
{ 0, 0, 6, 2 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 2, UNK_6_20, 3 },
|
|
{ 0, 3, UNK_6_20, 3 },
|
|
{ 0, 4, UNK_6_20, 3 },
|
|
{ 0, 0, 2, 2 },
|
|
{ 0, 0, 6, 2 },
|
|
{ 0, 0, 3, 2 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 0, 0, 2 },
|
|
{ 0, 0, 3, 2 },
|
|
{ 0, 0, 0, 3 },
|
|
{ 0, 0, 1, 2 },
|
|
{ 0, 0, 4, 3 },
|
|
{ 0, 0, 7, 3 },
|
|
{ 0, 0, 6, 1 },
|
|
{ 0, 0, 0, 3 },
|
|
{ 0, 0, 1, 3 },
|
|
{ 0, 0, 3, 3 },
|
|
{ FLAG_BANK_8, LV4_10_BOSSDIE, UNK_6_8, 3 },
|
|
{ 0, 0, 9, 0 },
|
|
{ 0, 0, 9, 1 },
|
|
{ 0, 0, 9, 3 },
|
|
{ 0, 0, 9, 3 },
|
|
{ 0, 0, 9, 3 },
|
|
{ 0, 0, 9, 3 },
|
|
{ 0, 0xffff, 0, 1 },
|
|
{ 0, 0xffff, 0, 1 },
|
|
{ 0, 0xffff, 0, 1 },
|
|
};
|
|
|
|
const Font gUnk_080FC844 = {
|
|
&gBG0Buffer[0xcf], BG_TILE_ADDR(0x198), gTextGfxBuffer, 0, 96, 224, 1, 1, 0, 1, 3, 0, 0, 1, 0
|
|
};
|
|
|
|
const u16 gUnk_080FC85C[][3] = {
|
|
{ 0, 3, SFX_MENU_ERROR },
|
|
{ 0, 4, SFX_MENU_ERROR },
|
|
{ 1, 5, 0 },
|
|
{ 0, 6, SFX_MENU_ERROR },
|
|
{ 1, 7, 0 },
|
|
{ 1, 8, 0 },
|
|
{ 0, 9, SFX_MENU_ERROR },
|
|
{ 1, 10, 0 },
|
|
{ 1, 11, 0 },
|
|
{ 0, 12, SFX_MENU_ERROR },
|
|
{ 1, 13, 0 },
|
|
{ 0, 14, 0 },
|
|
};
|
|
|
|
static void HandleFileScreenEnter(void);
|
|
static void HandleFileScreenActive(void);
|
|
static void HandleFileScreenExit(void);
|
|
static void (*const sTaskHandlers[])(void) = {
|
|
HandleFileScreenEnter,
|
|
HandleFileScreenActive,
|
|
HandleFileScreenExit,
|
|
};
|
|
|
|
static void HandleFileSelect(void);
|
|
extern void HandleFileNew(void);
|
|
static void HandleFileLanguageSelect(void);
|
|
extern void HandleFileOptions(void);
|
|
static void HandleFileView(void);
|
|
extern void HandleFileCopy(void);
|
|
extern void HandleFileDelete(void);
|
|
extern void HandleFileStart(void);
|
|
static void (*const sFileScreenSubHandlers[])(void) = {
|
|
HandleFileSelect, HandleFileNew, HandleFileLanguageSelect, HandleFileOptions,
|
|
HandleFileView, HandleFileCopy, HandleFileDelete, HandleFileStart,
|
|
};
|
|
|
|
static const KeyButtonLayout gUnk_080FC8D0 = {
|
|
.aButtonX = 0xFF,
|
|
.aButtonY = 0xD8,
|
|
.aButtonText = 0x0,
|
|
.bButtonX = 0xFF,
|
|
.bButtonY = 0xD8,
|
|
.bButtonText = 0x0,
|
|
.rButtonX = 0xE0,
|
|
.rButtonY = 0x10,
|
|
.rButtonText = 0xF,
|
|
.settingDict = { 0x5, 0x0, 0x2, 0x0, 0xFF },
|
|
};
|
|
|
|
static const u16 gUnk_080FC8DE[] = {
|
|
0x01, 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0xc0, 0xa0, 0x80, 0x60, 0x40, 0x20,
|
|
};
|
|
|
|
static void sub_08050848(void);
|
|
static void sub_0805086C(void);
|
|
static void sub_08050940(void);
|
|
void sub_08051358(void);
|
|
void sub_08051574(u32);
|
|
void sub_08051480(u32);
|
|
static void (*const sFileSelectDefaultHandlers[])(void) = {
|
|
sub_08050848,
|
|
sub_0805086C,
|
|
sub_08050940,
|
|
};
|
|
|
|
extern void (*const gUnk_080FC944[])(void);
|
|
extern void (*const gUnk_080FC950[])(void);
|
|
extern void (*const gUnk_080FC960[])(void);
|
|
extern void (*const gUnk_080FC9B0[])(void);
|
|
extern void (*const gUnk_080FC9BC[])(void);
|
|
extern void (*const gUnk_080FC9C8[])(void);
|
|
extern const u8 gUnk_080FC970[];
|
|
extern const u8 gUnk_080FC980[];
|
|
extern const u8 gUnk_080FC9A0[];
|
|
|
|
static void ResetEmptyOrDeletedSaveFile(u32);
|
|
static void sub_0805066C(void);
|
|
static void HideButtonR(void);
|
|
static void ShowButtonR(void);
|
|
void sub_08051458(void);
|
|
|
|
void sub_08050888(void);
|
|
void sub_080508E4(void);
|
|
void sub_08050910(void);
|
|
|
|
void CreateDialogBox(u32 arg0, u32 arg1) {
|
|
u32 sfx;
|
|
Font var0;
|
|
|
|
sub_08050384();
|
|
MemCopy(&gUnk_080FC844, &var0, sizeof(gUnk_080FC844));
|
|
sub_08056FEC(arg1, gUnk_020227E8);
|
|
var0.gfx_src |= gUnk_080FC85C[arg0][0] << 0xC;
|
|
ShowTextBox(gUnk_080FC85C[arg0][1], &var0);
|
|
sfx = gUnk_080FC85C[arg0][2];
|
|
if (sfx) {
|
|
SoundReq(sfx);
|
|
}
|
|
gScreen.bg0.updated = 1;
|
|
}
|
|
|
|
void sub_08050384(void) {
|
|
RecoverUI(0, 0);
|
|
MemClear(&gBG0Buffer, sizeof(gBG0Buffer));
|
|
gScreen.bg0.updated = 1;
|
|
}
|
|
|
|
void sub_080503A8(u32 gfxGroup) {
|
|
LoadGfxGroup(gfxGroup);
|
|
gScreen.bg1.updated = 1;
|
|
gScreen.bg2.updated = 1;
|
|
}
|
|
|
|
void SetFileSelectState(FileSelectState mode) {
|
|
gUI.state = mode;
|
|
MemClear(&gBG0Buffer, sizeof(gBG0Buffer));
|
|
MemClear(&gBG1Buffer, sizeof(gBG1Buffer));
|
|
}
|
|
|
|
void LoadOptionsFromSave(u32 idx) {
|
|
u8 msg_speed;
|
|
u8 brightness;
|
|
|
|
if (idx >= NUM_SAVE_SLOTS) {
|
|
// these apply to the language selection screen
|
|
msg_speed = 1;
|
|
brightness = 1;
|
|
} else {
|
|
SaveFile* saveFile = &gMapDataBottomSpecial.saves[idx];
|
|
msg_speed = saveFile->msg_speed;
|
|
brightness = saveFile->brightness;
|
|
}
|
|
|
|
gSaveHeader->msg_speed = msg_speed;
|
|
gSaveHeader->brightness = brightness;
|
|
gUsedPalettes = 0xffffffff;
|
|
}
|
|
|
|
void SetActiveSave(u32 idx) {
|
|
if (idx < NUM_SAVE_SLOTS) {
|
|
gSaveHeader->saveFileId = idx;
|
|
MemCopy(&gMapDataBottomSpecial.saves[idx], &gSave, sizeof(gMapDataBottomSpecial.saves[idx]));
|
|
}
|
|
LoadOptionsFromSave(idx);
|
|
}
|
|
|
|
void FileSelectTask(void) {
|
|
FlushSprites();
|
|
sTaskHandlers[gMain.state]();
|
|
if (gUI.lastState != gUI.state) {
|
|
gUI.lastState = gUI.state;
|
|
gScreen.bg0.xOffset = 0;
|
|
gScreen.bg0.yOffset = 0;
|
|
gScreen.bg1.xOffset = 0;
|
|
gScreen.bg1.yOffset = 0;
|
|
gScreen.bg2.xOffset = 0;
|
|
gScreen.bg2.yOffset = 0;
|
|
MemClear(&gChooseFileState, sizeof(gChooseFileState));
|
|
}
|
|
|
|
HideButtonR();
|
|
sFileScreenSubHandlers[gUI.lastState]();
|
|
|
|
gMapDataBottomSpecial.isTransitioning = FALSE;
|
|
UpdateEntities();
|
|
sub_0805066C();
|
|
UpdateUIElements();
|
|
DrawUIElements();
|
|
DrawEntities();
|
|
CopyOAM();
|
|
if (gMapDataBottomSpecial.unk3 != gSaveHeader->language) {
|
|
gMapDataBottomSpecial.unk3 = gSaveHeader->language;
|
|
sub_080503A8(0x6);
|
|
sub_080503A8(0xF);
|
|
}
|
|
}
|
|
|
|
static void HandleFileScreenEnter(void) {
|
|
u32 i;
|
|
|
|
DispReset(1);
|
|
InitSoundPlayingInfo();
|
|
MemClear((void*)VRAM, 0x80); // clear palettes
|
|
MessageInitialize();
|
|
EraseAllEntities();
|
|
ClearTileMaps();
|
|
ResetPalettes();
|
|
ResetPaletteTable(0);
|
|
MemClear(&gHUD, sizeof(gHUD));
|
|
MemClear(&gMapDataBottomSpecial, sizeof(gMapDataBottomSpecial));
|
|
gMapDataBottomSpecial.unk3 = 7;
|
|
gMapDataBottomSpecial.unk6 = gSaveHeader->language > LANGUAGE_EN ? 3 : 0;
|
|
MemClear(&gUI, sizeof(gUI));
|
|
gUI.lastState = 8;
|
|
SetFileSelectState(STATE_NONE);
|
|
InitDMA();
|
|
ResetEmptyOrDeletedSaveFile(0);
|
|
ResetEmptyOrDeletedSaveFile(1);
|
|
ResetEmptyOrDeletedSaveFile(2);
|
|
InitVBlankDMA();
|
|
sub_080503A8(0x5);
|
|
LoadPaletteGroup(0x9);
|
|
for (i = 0; i < 26; i++) {
|
|
CreateObject(FILE_SCREEN_OBJECTS, i, 0);
|
|
}
|
|
|
|
sub_080A70AC(&gUnk_080FC8D0);
|
|
HideButtonR();
|
|
gScreen.lcd.displayControl |= DISPCNT_BG_ALL_ON | DISPCNT_OBJ_ON;
|
|
gScreen.bg3.control = BGCNT_PRIORITY(3) | BGCNT_CHARBASE(2) | BGCNT_SCREENBASE(30);
|
|
gScreen.controls.layerFXControl = BLDCNT_TGT1_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_EFFECT_BLEND;
|
|
gScreen.controls.alphaBlend = BLDALPHA_BLEND(15, 10);
|
|
gGFXSlots.unk0 = 1;
|
|
gMain.state = GAMETASK_INIT;
|
|
SoundReq(BGM_FILE_SELECT);
|
|
SetFade(FADE_INSTANT, 8);
|
|
}
|
|
|
|
static void HandleFileScreenActive(void) {
|
|
}
|
|
|
|
static void HandleFileScreenExit(void) {
|
|
if (!gFadeControl.active) {
|
|
SetTask(TASK_GAME);
|
|
}
|
|
}
|
|
|
|
static void ResetEmptyOrDeletedSaveFile(u32 index) {
|
|
SaveFile* saveFile = &gMapDataBottomSpecial.saves[index];
|
|
int status = ReadSaveFile(index, saveFile);
|
|
switch (status) {
|
|
case SAVE_DELETED:
|
|
SetFileStatusDeleted(index);
|
|
// fallthrough
|
|
case SAVE_EMPTY:
|
|
ResetSaveFile(index);
|
|
break;
|
|
}
|
|
gMapDataBottomSpecial.saveStatus[index] = status;
|
|
}
|
|
|
|
static void sub_0805066C(void) {
|
|
u32 loadNewPalette;
|
|
const u8* paletteOffset;
|
|
|
|
loadNewPalette = FALSE;
|
|
if (--gMapDataBottomSpecial.unk1 == 0) {
|
|
gMapDataBottomSpecial.unk1 = 16;
|
|
gMapDataBottomSpecial.unk2 = (gMapDataBottomSpecial.unk2 + 1) % 15;
|
|
loadNewPalette = TRUE;
|
|
}
|
|
|
|
if (gMapDataBottomSpecial.unk2 == 0) {
|
|
gMapDataBottomSpecial.unk2 = 1;
|
|
gMapDataBottomSpecial.unk1 = (Random() & 0x7) * 16 + 8;
|
|
loadNewPalette = TRUE;
|
|
}
|
|
|
|
if (loadNewPalette) {
|
|
paletteOffset = &gGlobalGfxAndPalettes[gUnk_080FC8DE[gMapDataBottomSpecial.unk2]];
|
|
#ifdef EU
|
|
LoadPalettes(&paletteOffset[0x11A60], 11, 1);
|
|
LoadPalettes(&paletteOffset[0x11B60], 12, 1);
|
|
LoadPalettes(&paletteOffset[0x11C60], 13, 1);
|
|
LoadPalettes(&paletteOffset[0x11D60], 14, 1);
|
|
#else
|
|
LoadPalettes(&paletteOffset[0x11AA0], 11, 1);
|
|
LoadPalettes(&paletteOffset[0x11BA0], 12, 1);
|
|
LoadPalettes(&paletteOffset[0x11CA0], 13, 1);
|
|
LoadPalettes(&paletteOffset[0x11DA0], 14, 1);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void sub_0805070C(void) {
|
|
u32 i;
|
|
int j;
|
|
WStruct* var0;
|
|
char* name;
|
|
|
|
var0 = sub_0805F2C8();
|
|
if (var0) {
|
|
var0->charColor = 0;
|
|
var0->bgColor = 5;
|
|
var0->unk1 = 1;
|
|
var0->unk4 = 0x30;
|
|
var0->unk8 = gTextGfxBuffer;
|
|
for (i = 0; i < NUM_SAVE_SLOTS; i++) {
|
|
var0->unk6 = 0;
|
|
MemClear(var0->unk8, 0x200);
|
|
name = &gMapDataBottomSpecial.saves[i].name[0];
|
|
for (j = 0; j < FILENAME_LENGTH; j++) {
|
|
sub_0805F7DC(name[j], var0);
|
|
}
|
|
// i is a struct of size 0x200
|
|
MemCopy(var0->unk8, (void*)(OBJ_VRAM0 + 0x4000 + i * 0x200), 0x200);
|
|
}
|
|
sub_0805F300(var0);
|
|
}
|
|
}
|
|
|
|
void sub_08050790(void) {
|
|
u32 i, j;
|
|
WStruct* var0;
|
|
u32 var1;
|
|
|
|
var0 = sub_0805F2C8();
|
|
if (var0) {
|
|
var0->charColor = 0;
|
|
var0->bgColor = 5;
|
|
var0->unk1 = 1;
|
|
var0->unk4 = 0x80;
|
|
var0->unk8 = gTextGfxBuffer;
|
|
for (i = 0; i < 16; i++) {
|
|
var0->unk6 = 0;
|
|
var1 = i * 16;
|
|
for (j = 0; j < 16; j++) {
|
|
sub_0805F7DC(var1, var0);
|
|
var1++;
|
|
}
|
|
MemCopy(gTextGfxBuffer, (void*)(BG_VRAM + i * 0x400), 0x400);
|
|
}
|
|
sub_0805F300(var0);
|
|
}
|
|
}
|
|
|
|
static void HideButtonR(void) {
|
|
gHUD.buttonX[2] = 0x140;
|
|
gHUD.buttonY[2] = 0x24;
|
|
}
|
|
|
|
static void ShowButtonR(void) {
|
|
gHUD.buttonX[2] = 0xD0;
|
|
gHUD.buttonY[2] = 0x24;
|
|
}
|
|
|
|
static void HandleFileSelect(void) {
|
|
sFileSelectDefaultHandlers[gChooseFileState.state]();
|
|
sub_08050A64(gMapDataBottomSpecial.unk6);
|
|
}
|
|
|
|
void sub_08050848(void) {
|
|
sub_080503A8(0x7);
|
|
sub_0805070C();
|
|
gMapDataBottomSpecial.unk7 = 0;
|
|
sub_08050AFC(gMapDataBottomSpecial.unk6);
|
|
SetMenuType(1);
|
|
}
|
|
|
|
void (*const gUnk_080FC908[])(void) = {
|
|
sub_08050888,
|
|
sub_080508E4,
|
|
sub_08050910,
|
|
};
|
|
|
|
void sub_0805086C(void) {
|
|
gUnk_080FC908[gChooseFileState.subState]();
|
|
}
|
|
|
|
// transitioning away from submenu
|
|
void sub_08050888(void) {
|
|
if (!gFadeControl.active) {
|
|
switch (gMapDataBottomSpecial.saveStatus[gMapDataBottomSpecial.unk7]) {
|
|
case SAVE_EMPTY:
|
|
ResetSaveFile(gMapDataBottomSpecial.unk7);
|
|
gChooseFileState.subState = 2;
|
|
break;
|
|
case SAVE_VALID:
|
|
gChooseFileState.subState = 2;
|
|
break;
|
|
default:
|
|
ResetSaveFile(gMapDataBottomSpecial.unk7);
|
|
CreateDialogBox(0, gMapDataBottomSpecial.unk7 + 1);
|
|
gChooseFileState.timer = 30;
|
|
gChooseFileState.subState = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_080508E4(void) {
|
|
if (gChooseFileState.timer == 0) {
|
|
if (gInput.newKeys & (A_BUTTON | START_BUTTON)) {
|
|
gChooseFileState.subState = 2;
|
|
}
|
|
} else {
|
|
gChooseFileState.timer--;
|
|
}
|
|
}
|
|
|
|
void sub_08050910(void) {
|
|
sub_08050384();
|
|
if (++gMapDataBottomSpecial.unk7 > 2) {
|
|
SetMenuType(2);
|
|
} else {
|
|
gChooseFileState.subState = 0;
|
|
}
|
|
}
|
|
|
|
void sub_08050940(void) {
|
|
int row_idx;
|
|
u32 keys;
|
|
int num_rows;
|
|
FileSelectState mode;
|
|
|
|
if (gMapDataBottomSpecial.isTransitioning) {
|
|
return;
|
|
}
|
|
|
|
row_idx = gMapDataBottomSpecial.unk6;
|
|
keys = gInput.newKeys;
|
|
if ((gInput.heldKeys & L_BUTTON) && gMapDataBottomSpecial.saveStatus[row_idx] == SAVE_VALID) {
|
|
keys &= ~(DPAD_UP | DPAD_DOWN);
|
|
}
|
|
|
|
num_rows = gSaveHeader->language > 1 ? NUM_SAVE_SLOTS + 1 : NUM_SAVE_SLOTS;
|
|
mode = gUI.lastState;
|
|
switch (keys) {
|
|
case DPAD_UP:
|
|
if (row_idx > 0)
|
|
row_idx--;
|
|
break;
|
|
case DPAD_DOWN:
|
|
if (num_rows - 1 > row_idx)
|
|
row_idx++;
|
|
break;
|
|
case R_BUTTON:
|
|
if (gMapDataBottomSpecial.saveStatus[row_idx] == SAVE_VALID)
|
|
mode = STATE_OPTIONS;
|
|
break;
|
|
case A_BUTTON:
|
|
case START_BUTTON:
|
|
SetActiveSave(row_idx);
|
|
if (row_idx == 3)
|
|
mode = STATE_CHOOSE_LANG;
|
|
else
|
|
switch (gMapDataBottomSpecial.saveStatus[row_idx]) {
|
|
case SAVE_EMPTY:
|
|
mode = STATE_NEW;
|
|
break;
|
|
case SAVE_VALID:
|
|
mode = STATE_VIEW;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (gUI.lastState != mode) {
|
|
SetFileSelectState(mode);
|
|
SoundReq(SFX_TEXTBOX_SELECT);
|
|
}
|
|
|
|
row_idx = (row_idx + num_rows) % num_rows;
|
|
if (gMapDataBottomSpecial.unk6 != row_idx) {
|
|
gMapDataBottomSpecial.unk6 = row_idx;
|
|
sub_08050AFC(row_idx);
|
|
SoundReq(SFX_TEXTBOX_CHOICE);
|
|
}
|
|
|
|
if (gMapDataBottomSpecial.saveStatus[gMapDataBottomSpecial.unk6] == SAVE_VALID) {
|
|
ShowButtonR();
|
|
}
|
|
}
|
|
|
|
void sub_08050A64(u32 idx) {
|
|
if (gMapDataBottomSpecial.saveStatus[idx] != SAVE_VALID) {
|
|
return;
|
|
}
|
|
|
|
gOamCmd._4 = 0;
|
|
gOamCmd._6 = 0;
|
|
gOamCmd._8 = 0x400;
|
|
|
|
// Draw the save file's obtained elements.
|
|
if (GetInventoryValue(ITEM_EARTH_ELEMENT)) {
|
|
gOamCmd.x = 0xA2;
|
|
gOamCmd.y = 0x36;
|
|
#ifdef EU
|
|
DrawDirect(0x144, 0x24);
|
|
#else
|
|
DrawDirect(0x145, 0x24);
|
|
#endif
|
|
}
|
|
if (GetInventoryValue(ITEM_FIRE_ELEMENT)) {
|
|
gOamCmd.x = 0x96;
|
|
gOamCmd.y = 0x3D;
|
|
#ifdef EU
|
|
DrawDirect(0x144, 0x22);
|
|
#else
|
|
DrawDirect(0x145, 0x22);
|
|
#endif
|
|
}
|
|
if (GetInventoryValue(ITEM_WATER_ELEMENT)) {
|
|
gOamCmd.x = 0xAE;
|
|
gOamCmd.y = 0x3D;
|
|
#ifdef EU
|
|
DrawDirect(0x144, 0x23);
|
|
#else
|
|
DrawDirect(0x145, 0x23);
|
|
#endif
|
|
}
|
|
if (GetInventoryValue(ITEM_WIND_ELEMENT)) {
|
|
gOamCmd.x = 0xA2;
|
|
gOamCmd.y = 0x44;
|
|
#ifdef EU
|
|
DrawDirect(0x144, 0x21);
|
|
#else
|
|
DrawDirect(0x145, 0x21);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void sub_08050B3C(u16*);
|
|
|
|
void sub_08050AFC(u32 idx) {
|
|
SetActiveSave(idx);
|
|
MemClear(&gBG1Buffer, sizeof(gBG1Buffer));
|
|
if (gMapDataBottomSpecial.saveStatus[idx] == SAVE_VALID) {
|
|
sub_08050B3C(&gBG1Buffer[0x14E]);
|
|
}
|
|
gScreen.bg1.updated = 1;
|
|
}
|
|
|
|
typedef struct {
|
|
u16* unk0;
|
|
u32 unk4;
|
|
} unk_08050B3C;
|
|
|
|
extern const u16 gUnk_080FC914[];
|
|
|
|
const u16 gUnk_080FC914[] = { 0xf251, 0xf251, 0xf251, 0xf251, 0xf251, 0xf251, 0xf251, 0xf251, 0xf251, 0xf251,
|
|
0xf24d, 0xf24d, 0xf24d, 0xf24d, 0xf24d, 0xf24d, 0xf24d, 0xf24d, 0xf24d, 0xf24d };
|
|
|
|
// Handles drawing of hearts
|
|
void sub_08050B3C(u16* target) {
|
|
s32 currentQuarterHearts;
|
|
s32 maxQuarterHearts;
|
|
s32 maxHeartsFirstRow;
|
|
s32 currentFullHearts;
|
|
s32 maxHeartsSecondRow;
|
|
u32 currentFullHeartsFirstRow;
|
|
s32 currentFullHeartsSecondRow;
|
|
u16* temp_target;
|
|
u32 currentPartialHeartValue;
|
|
u32 maxHearts;
|
|
|
|
currentQuarterHearts = gSave.stats.health / 2;
|
|
if (currentQuarterHearts == 0) {
|
|
currentQuarterHearts = 1;
|
|
}
|
|
|
|
maxQuarterHearts = gSave.stats.maxHealth / 2;
|
|
if (maxQuarterHearts == 0) {
|
|
return;
|
|
}
|
|
|
|
if (currentQuarterHearts > maxQuarterHearts) {
|
|
currentQuarterHearts = maxQuarterHearts;
|
|
}
|
|
|
|
currentPartialHeartValue = currentQuarterHearts & 3;
|
|
currentFullHearts = currentQuarterHearts / 4;
|
|
currentFullHeartsFirstRow = currentFullHearts;
|
|
if (currentFullHearts > 10) {
|
|
currentFullHeartsFirstRow = 10;
|
|
}
|
|
|
|
currentFullHeartsSecondRow = currentFullHearts - 10;
|
|
if (currentFullHeartsSecondRow < 0) {
|
|
currentFullHeartsSecondRow = 0;
|
|
}
|
|
|
|
maxHearts = maxQuarterHearts / 4;
|
|
maxHeartsFirstRow = maxHearts;
|
|
if (maxHeartsFirstRow > 10) {
|
|
maxHeartsFirstRow = 10;
|
|
}
|
|
maxHeartsSecondRow = maxHearts - 10;
|
|
temp_target = target;
|
|
temp_target[0] = 0xF24C;
|
|
DmaCopy16(3, &gUnk_080FC914[10 - currentFullHeartsFirstRow], &temp_target[1], maxHeartsFirstRow * 2);
|
|
if (maxHeartsSecondRow > 0) {
|
|
temp_target += 0x20;
|
|
temp_target[0] = 0xF24C;
|
|
DmaCopy16(3, &gUnk_080FC914[10 - currentFullHeartsSecondRow], &temp_target[1], maxHeartsSecondRow * 2);
|
|
}
|
|
|
|
if (!currentPartialHeartValue) {
|
|
return;
|
|
}
|
|
|
|
temp_target = target;
|
|
if (currentFullHearts >= 10) {
|
|
currentFullHearts = currentFullHearts - 10;
|
|
temp_target += 0x20;
|
|
}
|
|
|
|
temp_target[currentFullHearts + 1] = currentPartialHeartValue - 0xDB3;
|
|
}
|
|
|
|
void sub_08050C54(void);
|
|
void sub_08050D68(void);
|
|
|
|
void (*const gUnk_080FC93C[])() = {
|
|
sub_08050C54,
|
|
sub_08050D68,
|
|
};
|
|
|
|
void HandleFileView(void) {
|
|
gUnk_080FC93C[gMenu.menuType]();
|
|
sub_08050A64(gMapDataBottomSpecial.unk6);
|
|
}
|
|
|
|
void sub_08050C54(void) {
|
|
s32 column_idx;
|
|
|
|
if (gMapDataBottomSpecial.isTransitioning)
|
|
return;
|
|
|
|
column_idx = gMenu.column_idx;
|
|
switch (gInput.newKeys) {
|
|
case A_BUTTON:
|
|
case START_BUTTON:
|
|
if (column_idx == 0) {
|
|
SoundReq(SONG_VOL_FADE_OUT);
|
|
}
|
|
gMenu.transitionTimer = 15;
|
|
SetMenuType(1);
|
|
SoundReq(SFX_TEXTBOX_SELECT);
|
|
break;
|
|
case B_BUTTON:
|
|
SoundReq(SFX_MENU_CANCEL);
|
|
SetFileSelectState(STATE_NONE);
|
|
break;
|
|
case DPAD_LEFT:
|
|
column_idx--;
|
|
break;
|
|
case DPAD_RIGHT:
|
|
column_idx++;
|
|
break;
|
|
}
|
|
if (column_idx < 0) {
|
|
column_idx = 0;
|
|
}
|
|
if (column_idx >= NUM_FILE_OPERATIONS) {
|
|
column_idx = NUM_FILE_OPERATIONS - 1;
|
|
}
|
|
if (gMenu.column_idx != column_idx) {
|
|
gMenu.column_idx = column_idx;
|
|
SoundReq(SFX_TEXTBOX_CHOICE);
|
|
}
|
|
}
|
|
|
|
void sub_08050D68(void) {
|
|
u32 state;
|
|
|
|
if (gMenu.transitionTimer == 0) {
|
|
switch (gMenu.column_idx) {
|
|
default:
|
|
case 0:
|
|
state = STATE_START;
|
|
break;
|
|
case 1:
|
|
state = STATE_COPY;
|
|
break;
|
|
case 2:
|
|
state = STATE_ERASE;
|
|
break;
|
|
}
|
|
SetFileSelectState(state);
|
|
} else {
|
|
gMenu.transitionTimer--;
|
|
}
|
|
}
|
|
|
|
void sub_08050DB8(void);
|
|
void sub_08050DE4(void);
|
|
void sub_08050E88(void);
|
|
void (*const gUnk_080FC944[])(void) = {
|
|
sub_08050DB8,
|
|
sub_08050DE4,
|
|
sub_08050E88,
|
|
};
|
|
|
|
void HandleFileLanguageSelect(void) {
|
|
gUnk_080FC944[gMenu.menuType]();
|
|
}
|
|
|
|
void sub_08050DB8(void) {
|
|
MemClear(&gBG2Buffer, sizeof(gBG2Buffer));
|
|
sub_080503A8(0xc);
|
|
gMenu.field_0x4 = gSaveHeader->language;
|
|
SetMenuType(1);
|
|
}
|
|
|
|
void sub_08050DE4(void) {
|
|
s32 row_idx;
|
|
|
|
if (gMapDataBottomSpecial.isTransitioning)
|
|
return;
|
|
|
|
row_idx = gSaveHeader->language;
|
|
switch (gInput.newKeys) {
|
|
case DPAD_UP:
|
|
row_idx--;
|
|
break;
|
|
case DPAD_DOWN:
|
|
row_idx++;
|
|
break;
|
|
case A_BUTTON:
|
|
case START_BUTTON:
|
|
SoundReq(SFX_TEXTBOX_SELECT);
|
|
if (gMenu.field_0x4 != row_idx) {
|
|
SetMenuType(2);
|
|
CreateDialogBox(8, 0);
|
|
} else {
|
|
SetFileSelectState(STATE_NONE);
|
|
}
|
|
break;
|
|
case B_BUTTON:
|
|
row_idx = gMenu.field_0x4;
|
|
gSaveHeader->language = gMenu.field_0x4;
|
|
SoundReq(SFX_MENU_CANCEL);
|
|
SetFileSelectState(STATE_NONE);
|
|
break;
|
|
}
|
|
|
|
// Lazy solution for positioning the rows lower on the screen
|
|
if (row_idx < 2) {
|
|
row_idx = 2;
|
|
}
|
|
if (row_idx > 6) {
|
|
row_idx = 6;
|
|
}
|
|
if (gSaveHeader->language != row_idx) {
|
|
gSaveHeader->language = row_idx;
|
|
SoundReq(SFX_TEXTBOX_CHOICE);
|
|
}
|
|
}
|
|
|
|
void sub_08050E88(void) {
|
|
if (HandleSave(2))
|
|
SetFileSelectState(0);
|
|
}
|
|
|
|
void sub_08050EB8(void);
|
|
void sub_08050EF4(void);
|
|
void sub_08050FFC(void);
|
|
void sub_0805103C(void);
|
|
void (*const gUnk_080FC950[])(void) = {
|
|
sub_08050EB8,
|
|
sub_08050EF4,
|
|
sub_08050FFC,
|
|
sub_0805103C,
|
|
};
|
|
|
|
void HandleFileOptions(void) {
|
|
gUnk_080FC950[gMenu.menuType]();
|
|
}
|
|
|
|
void sub_08050EB8(void) {
|
|
SaveFile* save;
|
|
sub_080503A8(0xe);
|
|
save = &gMapDataBottomSpecial.saves[gMapDataBottomSpecial.unk6];
|
|
gMapDataBottomSpecial.unk4 = save->msg_speed;
|
|
gMapDataBottomSpecial.unk5 = save->brightness;
|
|
gMenu.column_idx = 0;
|
|
gMenu.transitionTimer = 255;
|
|
SetMenuType(1);
|
|
}
|
|
|
|
void sub_08050EF4(void) {
|
|
u8* p_option;
|
|
u32 option;
|
|
char column_idx;
|
|
u8 mode;
|
|
|
|
if (gMapDataBottomSpecial.isTransitioning == 0) {
|
|
SaveFile* currentFile = &gMapDataBottomSpecial.saves[gMapDataBottomSpecial.unk6];
|
|
column_idx = gMenu.column_idx;
|
|
|
|
if (column_idx == 0) {
|
|
p_option = ¤tFile->msg_speed;
|
|
} else {
|
|
p_option = ¤tFile->brightness;
|
|
}
|
|
|
|
option = *p_option;
|
|
mode = 0;
|
|
switch (gInput.newKeys) {
|
|
case DPAD_UP:
|
|
column_idx = 0;
|
|
break;
|
|
case DPAD_DOWN:
|
|
column_idx = 1;
|
|
break;
|
|
case DPAD_LEFT:
|
|
if (option != 0) {
|
|
option--;
|
|
}
|
|
break;
|
|
case DPAD_RIGHT:
|
|
if (option < 2) {
|
|
option++;
|
|
}
|
|
break;
|
|
|
|
case A_BUTTON:
|
|
case START_BUTTON:
|
|
if (gMapDataBottomSpecial.unk4 != currentFile->msg_speed ||
|
|
gMapDataBottomSpecial.unk5 != currentFile->brightness) {
|
|
mode = 2;
|
|
break;
|
|
}
|
|
case B_BUTTON:
|
|
mode = 3;
|
|
break;
|
|
}
|
|
|
|
if (mode != 0) {
|
|
switch (mode) {
|
|
case 2:
|
|
CreateDialogBox(8, 0);
|
|
SoundReq(SFX_TEXTBOX_SELECT);
|
|
break;
|
|
case 3:
|
|
currentFile->msg_speed = gMapDataBottomSpecial.unk4;
|
|
currentFile->brightness = gMapDataBottomSpecial.unk5;
|
|
SoundReq(SFX_MENU_CANCEL);
|
|
break;
|
|
}
|
|
SetMenuType(mode);
|
|
SetActiveSave(gMapDataBottomSpecial.unk6);
|
|
} else if (gMenu.column_idx != column_idx) {
|
|
gMenu.column_idx = column_idx;
|
|
SoundReq(SFX_TEXTBOX_CHOICE);
|
|
} else if (option != *p_option) {
|
|
*p_option = option;
|
|
LoadOptionsFromSave(gMapDataBottomSpecial.unk6);
|
|
SoundReq(SFX_TEXTBOX_CHOICE);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_08050FFC(void) {
|
|
switch (HandleSave(0)) {
|
|
case SAVE_ERROR:
|
|
gMenu.transitionTimer = 30;
|
|
ResetSaveFile(gMapDataBottomSpecial.unk6);
|
|
CreateDialogBox(9, 0);
|
|
case SAVE_OK:
|
|
SetMenuType(3);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sub_0805103C(void) {
|
|
// this gets optimized as a ldrb
|
|
switch (gMenu.transitionTimer % 256) {
|
|
case 0:
|
|
if (!(gInput.newKeys & (A_BUTTON | START_BUTTON)))
|
|
return;
|
|
default:
|
|
gMenu.transitionTimer--;
|
|
break;
|
|
case 255:
|
|
SetFileSelectState(STATE_NONE);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sub_08051090(void);
|
|
void sub_080610B8(void);
|
|
void sub_0805138C(void);
|
|
void sub_0805144C(void);
|
|
void (*const gUnk_080FC960[])(void) = {
|
|
sub_08051090,
|
|
sub_080610B8,
|
|
sub_0805138C,
|
|
sub_0805144C,
|
|
};
|
|
|
|
void HandleFileNew(void) {
|
|
gUnk_080FC960[gMenu.menuType]();
|
|
}
|
|
|
|
void sub_08051090(void) {
|
|
sub_080503A8(8);
|
|
sub_08050790();
|
|
sub_0805070C();
|
|
sub_08051458();
|
|
gScreen.bg1.yOffset = 0xff;
|
|
gScreen.bg2.yOffset = 0xff;
|
|
SetMenuType(1);
|
|
}
|
|
|
|
const u8 gUnk_080FC970[] = {
|
|
1, 2, 3, 5, 8, 0, 0, 0, 1, 2, 5, 8, 0, 0, 0, 0,
|
|
};
|
|
const u8 gUnk_080FC980[] = {
|
|
0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 0, 0, 0,
|
|
};
|
|
const u8 gUnk_080FC9A0[] = {
|
|
1, 3, 6, 8, 11, 0, 0, 0, 1, 4, 7, 11, 11, 0, 0, 0,
|
|
};
|
|
|
|
void sub_080610B8(void) {
|
|
u8 uVar7;
|
|
s32 uVar6;
|
|
s32 tmp4;
|
|
const u8* puVar3;
|
|
const u8* puVar4;
|
|
const u8* puVar5;
|
|
s32 iVar4;
|
|
u8 bVar2;
|
|
u32 tmp1;
|
|
u32 tmp3;
|
|
u8 tmp2;
|
|
u8 cVar1;
|
|
s32 uVar8;
|
|
s32 uVar5;
|
|
|
|
if (gMapDataBottomSpecial.isTransitioning != 0) {
|
|
return;
|
|
}
|
|
uVar7 = 0;
|
|
switch (gInput.newKeys) {
|
|
default:
|
|
uVar6 = 0;
|
|
tmp4 = 0;
|
|
switch (gInput.menuScrollKeys) {
|
|
case DPAD_UP:
|
|
tmp4 = -1;
|
|
break;
|
|
case DPAD_DOWN:
|
|
tmp4 = 1;
|
|
break;
|
|
case DPAD_LEFT:
|
|
uVar6 = -1;
|
|
break;
|
|
case DPAD_RIGHT:
|
|
uVar6 = 1;
|
|
break;
|
|
}
|
|
gGenericMenu.unk10.a[1] = (gGenericMenu.unk10.a[1] + tmp4 + 6) % 6;
|
|
if ((tmp4 | uVar6) != 0) {
|
|
SoundReq(SFX_TEXTBOX_NEXT);
|
|
}
|
|
if (uVar6 != 0) {
|
|
if (gGenericMenu.unk10.a[1] != 5) {
|
|
gGenericMenu.unk10.a[0] = (gGenericMenu.unk10.a[0] + uVar6 + 0xd) % 0xd;
|
|
puVar4 = gUnk_080FC980;
|
|
if (gSaveHeader->language != 0) {
|
|
puVar4 += 0x10;
|
|
}
|
|
gGenericMenu.unk10.a[2] = puVar4[gGenericMenu.unk10.a[0]];
|
|
} else {
|
|
if (gSaveHeader->language == 0) {
|
|
iVar4 = 5;
|
|
} else {
|
|
iVar4 = 4;
|
|
}
|
|
gGenericMenu.unk10.a[2] = (gGenericMenu.unk10.a[2] + uVar6 + iVar4) % iVar4;
|
|
if (gSaveHeader->language != 0) {
|
|
puVar5 = gUnk_080FC9A0 + 8;
|
|
} else {
|
|
puVar5 = gUnk_080FC9A0;
|
|
}
|
|
gGenericMenu.unk10.a[0] = puVar5[gGenericMenu.unk10.a[2]];
|
|
}
|
|
}
|
|
break;
|
|
case B_BUTTON:
|
|
if (gGenericMenu.unk10.a[3] != 0) {
|
|
uVar7 = 5;
|
|
} else {
|
|
sub_08051358();
|
|
}
|
|
break;
|
|
case START_BUTTON:
|
|
if (gSaveHeader->language == 0) {
|
|
iVar4 = 4;
|
|
} else {
|
|
iVar4 = 3;
|
|
}
|
|
if ((gGenericMenu.unk10.a[1] == 5) && (iVar4 == gGenericMenu.unk10.a[2])) {
|
|
uVar7 = 8;
|
|
} else {
|
|
sub_08051358();
|
|
}
|
|
break;
|
|
case A_BUTTON:
|
|
if (gGenericMenu.unk10.a[1] == 5) {
|
|
puVar3 = gUnk_080FC970;
|
|
tmp1 = gGenericMenu.unk10.a[2];
|
|
if (gSaveHeader->language != 0) {
|
|
tmp1 += 8;
|
|
}
|
|
uVar7 = puVar3[tmp1];
|
|
|
|
} else {
|
|
uVar7 = 6;
|
|
}
|
|
break;
|
|
case L_BUTTON:
|
|
if (gSaveHeader->language == 0) {
|
|
uVar7 = 4;
|
|
} else {
|
|
uVar7 = 1;
|
|
}
|
|
break;
|
|
case R_BUTTON:
|
|
if (gSaveHeader->language == 0) {
|
|
uVar7 = 7;
|
|
} else {
|
|
uVar7 = 2;
|
|
}
|
|
break;
|
|
}
|
|
tmp3 = gMenu.column_idx;
|
|
switch (uVar7) {
|
|
case 1:
|
|
tmp3 = 0;
|
|
break;
|
|
case 2:
|
|
tmp3 = 1;
|
|
break;
|
|
case 3:
|
|
tmp3 = 2;
|
|
break;
|
|
case 4:
|
|
tmp3++;
|
|
break;
|
|
case 5:
|
|
if (gGenericMenu.unk10.a[3] != 0) {
|
|
gGenericMenu.unk10.a[3]--;
|
|
gSave.name[gGenericMenu.unk10.a[3]] = 0;
|
|
gSave.name[gGenericMenu.unk10.a[3] + 1] = 0;
|
|
sub_08051574(0x6c);
|
|
}
|
|
break;
|
|
case 7:
|
|
sub_08051480(0);
|
|
break;
|
|
case 6:
|
|
tmp2 = ((gBG3Buffer[gGenericMenu.unk10.a[0] * 2 + 0xc3 + gGenericMenu.unk10.a[1] * 0x40]) >> 1);
|
|
sub_08051480(tmp2);
|
|
break;
|
|
case 8:
|
|
uVar8 = 5;
|
|
do {
|
|
cVar1 = gSave.name[uVar8];
|
|
if ((cVar1 != 0) && (cVar1 != 0x20)) {
|
|
break;
|
|
}
|
|
gSave.name[uVar8] = 0;
|
|
uVar8--;
|
|
} while (0 <= uVar8);
|
|
if (gSave.name[0] != 0) {
|
|
uVar7 = 2;
|
|
} else {
|
|
uVar7 = 3;
|
|
}
|
|
sub_08051574(0x6a);
|
|
SetMenuType(uVar7);
|
|
}
|
|
if (gSaveHeader->language == 0) {
|
|
iVar4 = 3;
|
|
} else {
|
|
iVar4 = 2;
|
|
}
|
|
tmp3 = (s32)(tmp3 + iVar4) % (iVar4);
|
|
if (gMenu.column_idx != tmp3) {
|
|
gMenu.column_idx = tmp3;
|
|
sub_08051458();
|
|
SoundReq(SFX_TEXTBOX_SWAP);
|
|
}
|
|
}
|
|
|
|
void sub_08051358(void) {
|
|
gGenericMenu.unk10.a[2] = gSaveHeader->language == 0 ? 4 : 3;
|
|
|
|
if (gGenericMenu.unk10.a[0] != 0x0b || gGenericMenu.unk10.a[1] != 0x5) {
|
|
gGenericMenu.unk10.a[1] = 0x5;
|
|
gGenericMenu.unk10.a[0] = 0xb;
|
|
SoundReq(SFX_TEXTBOX_NEXT);
|
|
}
|
|
}
|
|
|
|
void sub_080513A8(void);
|
|
void sub_080513C0(void);
|
|
void sub_0805141C(void);
|
|
void (*const gUnk_080FC9B0[])(void) = {
|
|
sub_080513A8,
|
|
sub_080513C0,
|
|
sub_0805141C,
|
|
};
|
|
|
|
void sub_0805138C(void) {
|
|
gUnk_080FC9B0[gMenu.overlayType]();
|
|
}
|
|
|
|
void sub_080513A8(void) {
|
|
CreateDialogBox(5, 0);
|
|
gMenu.overlayType = 1;
|
|
}
|
|
|
|
void sub_080513C0(void) {
|
|
switch (HandleSave(0)) {
|
|
case 1:
|
|
gMapDataBottomSpecial.saveStatus[gMapDataBottomSpecial.unk6] = 1;
|
|
SetMenuType(3);
|
|
break;
|
|
case 0:
|
|
break;
|
|
case -1:
|
|
ResetSaveFile(gMapDataBottomSpecial.unk6);
|
|
CreateDialogBox(6, 0);
|
|
gMenu.transitionTimer = 30;
|
|
gMenu.overlayType = 2;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sub_0805141C(void) {
|
|
switch (gMenu.transitionTimer) {
|
|
case 0:
|
|
if (gInput.newKeys & (A_BUTTON | START_BUTTON)) {
|
|
SetMenuType(3);
|
|
}
|
|
break;
|
|
default:
|
|
gMenu.transitionTimer--;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sub_0805144C(void) {
|
|
SetFileSelectState(STATE_NONE);
|
|
}
|
|
|
|
void sub_08051458(void) {
|
|
sub_080503A8(gMenu.column_idx + 9);
|
|
MemCopy(&gBG3Buffer[0x80], &gBG1Buffer[0x80], 0x400);
|
|
}
|
|
|
|
u32 sub_080514BC(u32);
|
|
|
|
void sub_08051480(u32 c) {
|
|
CharResult result;
|
|
u32 idx;
|
|
|
|
result = sub_080514BC(c);
|
|
idx = gGenericMenu.unk10.a[3];
|
|
|
|
if (result == RESULT_INVALID) {
|
|
return;
|
|
}
|
|
|
|
if (result != RESULT_ASCII) {
|
|
c = result;
|
|
idx--;
|
|
}
|
|
|
|
if (idx > FILENAME_LENGTH - 1) {
|
|
idx = FILENAME_LENGTH - 1;
|
|
}
|
|
|
|
gGenericMenu.unk10.a[3] = idx + 1;
|
|
gSave.name[idx] = c;
|
|
sub_08051574(SFX_6B);
|
|
}
|
|
|
|
u32 sub_080514BC(u32 a1) {
|
|
u32 c;
|
|
u32 idx;
|
|
|
|
if (gSaveHeader->language != 0)
|
|
return 1;
|
|
|
|
switch (a1) {
|
|
case 0x0:
|
|
case 0xe:
|
|
case 0xf:
|
|
break;
|
|
default:
|
|
return 1;
|
|
}
|
|
|
|
idx = gGenericMenu.unk10.a[3];
|
|
if (idx == 0)
|
|
return 0;
|
|
|
|
c = gSave.name[idx - 1];
|
|
if (c - 0xa4 < 0x29) {
|
|
switch (a1) {
|
|
case 0x0:
|
|
if (c < 0xc3) {
|
|
return c + 0x33;
|
|
} else {
|
|
return c + 10;
|
|
}
|
|
case 0xE:
|
|
return c;
|
|
case 0xF:
|
|
if (c < 0xc3)
|
|
return 0;
|
|
else
|
|
return c + 10;
|
|
default:
|
|
return c;
|
|
}
|
|
}
|
|
|
|
if (c - 0xcd < 10) {
|
|
switch (a1) {
|
|
case 0xf:
|
|
return c;
|
|
case 0x0:
|
|
return c + 0x29;
|
|
case 0xe:
|
|
return c - 10;
|
|
}
|
|
}
|
|
|
|
if (c - 0xd7 < 0x29) {
|
|
switch (a1) {
|
|
default:
|
|
case 0x0:
|
|
case 0xe:
|
|
return c - 0x33;
|
|
case 0xf:
|
|
if (c > 0xf5)
|
|
return c - 0x29;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void sub_08051574(u32 sfx) {
|
|
SoundReq(sfx);
|
|
MemCopy(&gSave, &gMapDataBottomSpecial.saves[gMapDataBottomSpecial.unk6],
|
|
sizeof(gMapDataBottomSpecial.saves[gMapDataBottomSpecial.unk6]));
|
|
sub_0805070C();
|
|
}
|
|
|
|
void sub_080515C8(void);
|
|
void sub_080515D4(void);
|
|
void sub_080516E0(void);
|
|
void (*const gUnk_080FC9BC[])(void) = {
|
|
sub_080515C8,
|
|
sub_080515D4,
|
|
sub_080516E0,
|
|
};
|
|
|
|
void HandleFileDelete(void) {
|
|
gUnk_080FC9BC[gMenu.menuType]();
|
|
sub_08050A64(gMapDataBottomSpecial.unk6);
|
|
}
|
|
|
|
void sub_080515C8(void) {
|
|
SetMenuType(1);
|
|
}
|
|
|
|
void sub_080515D4(void) {
|
|
u32 column_idx;
|
|
|
|
if (gMapDataBottomSpecial.isTransitioning)
|
|
return;
|
|
|
|
gMenu.transitionTimer = 4;
|
|
column_idx = gMenu.column_idx;
|
|
switch (gInput.newKeys) {
|
|
case B_BUTTON:
|
|
gMenu.column_idx = 0; // ??
|
|
column_idx = 0;
|
|
case A_BUTTON:
|
|
case START_BUTTON:
|
|
if (column_idx == 1) {
|
|
CreateDialogBox(4, 0);
|
|
SetMenuType(2);
|
|
SoundReq(SFX_TEXTBOX_SELECT);
|
|
} else {
|
|
SetFileSelectState(0);
|
|
SoundReq(SFX_MENU_CANCEL);
|
|
}
|
|
break;
|
|
case DPAD_LEFT:
|
|
column_idx = 0;
|
|
break;
|
|
case DPAD_RIGHT:
|
|
column_idx = 1;
|
|
break;
|
|
}
|
|
|
|
if (gMenu.column_idx != column_idx) {
|
|
gMenu.column_idx = column_idx;
|
|
SoundReq(SFX_TEXTBOX_CHOICE);
|
|
}
|
|
}
|
|
|
|
void sub_080516E0(void) {
|
|
if (HandleSave(1)) {
|
|
ResetSaveFile(gMapDataBottomSpecial.unk6);
|
|
sub_08050AFC(gMapDataBottomSpecial.unk6);
|
|
gMenu.transitionTimer = 2;
|
|
SetFileSelectState(0);
|
|
}
|
|
}
|
|
|
|
void sub_08051738(void);
|
|
void sub_080517EC(void);
|
|
void sub_08051874(void);
|
|
void sub_080518E4(void);
|
|
void (*const gUnk_080FC9C8[])(void) = {
|
|
sub_08051738,
|
|
sub_080517EC,
|
|
sub_08051874,
|
|
sub_080518E4,
|
|
};
|
|
|
|
void HandleFileCopy(void) {
|
|
gUnk_080FC9C8[gMenu.menuType]();
|
|
sub_08050A64(gMapDataBottomSpecial.unk6);
|
|
}
|
|
|
|
void sub_08051738(void) {
|
|
s32 temp;
|
|
u32 i;
|
|
s32 uVar3;
|
|
s32 val;
|
|
u32 temp2;
|
|
|
|
gMapDataBottomSpecial.unk7 = 4;
|
|
uVar3 = 0;
|
|
for (i = 0; i < 3; i++) {
|
|
if (gMapDataBottomSpecial.saveStatus[i] == 1) {
|
|
temp = gMapDataBottomSpecial.unk6;
|
|
val = 4;
|
|
if ((temp ^ i) == 0) {
|
|
val = 0;
|
|
}
|
|
} else {
|
|
uVar3++;
|
|
val = uVar3;
|
|
}
|
|
gGenericMenu.unk10.a[i] = val;
|
|
}
|
|
if (uVar3 == 0) {
|
|
gMenu.transitionTimer = 60;
|
|
CreateDialogBox(1, 0);
|
|
SetMenuType(3);
|
|
} else {
|
|
SetMenuType(1);
|
|
}
|
|
uVar3++;
|
|
gGenericMenu.unk16 = uVar3;
|
|
gGenericMenu.unk10.a[3] = 4;
|
|
gGenericMenu.unk14 = uVar3;
|
|
}
|
|
|
|
s32 sub_080517B4(s32 a1) {
|
|
u32 i = gMapDataBottomSpecial.unk7;
|
|
if (a1 != 0) {
|
|
for (i = i + a1; i < 5; i += a1) {
|
|
if (gGenericMenu.unk10.a[i] != 0 && gGenericMenu.unk10.a[i] != 4)
|
|
return i;
|
|
}
|
|
|
|
i = gMapDataBottomSpecial.unk7;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
void sub_080517EC(void) {
|
|
u32 temp;
|
|
s32 delta;
|
|
|
|
if (gMapDataBottomSpecial.isTransitioning)
|
|
return;
|
|
|
|
delta = 0;
|
|
switch (gInput.newKeys) {
|
|
case DPAD_UP:
|
|
delta = -1;
|
|
break;
|
|
case DPAD_DOWN:
|
|
delta = 1;
|
|
break;
|
|
case A_BUTTON:
|
|
case START_BUTTON:
|
|
if (gMapDataBottomSpecial.unk7 < 3) {
|
|
CreateDialogBox(2, 0);
|
|
SetMenuType(2);
|
|
SoundReq(SFX_TEXTBOX_SELECT);
|
|
break;
|
|
}
|
|
// fallthrough
|
|
case B_BUTTON:
|
|
gMapDataBottomSpecial.unk7 = 4;
|
|
SoundReq(SFX_MENU_CANCEL);
|
|
SetFileSelectState(0);
|
|
break;
|
|
}
|
|
temp = sub_080517B4(delta);
|
|
if (temp != gMapDataBottomSpecial.unk7) {
|
|
gMapDataBottomSpecial.unk7 = temp;
|
|
SoundReq(SFX_TEXTBOX_CHOICE);
|
|
}
|
|
}
|
|
|
|
void sub_08051874(void) {
|
|
s32 temp;
|
|
gSaveHeader->saveFileId = gMapDataBottomSpecial.unk7;
|
|
temp = HandleSave(0);
|
|
gMapDataBottomSpecial.saveStatus[gMapDataBottomSpecial.unk7] = temp;
|
|
switch (temp) {
|
|
case 1:
|
|
MemCopy(&gSave, &gMapDataBottomSpecial.saves[gMapDataBottomSpecial.unk7],
|
|
sizeof(gMapDataBottomSpecial.saves[gMapDataBottomSpecial.unk7]));
|
|
SetFileSelectState(0);
|
|
break;
|
|
case -1:
|
|
ResetSaveFile(gMapDataBottomSpecial.unk7);
|
|
CreateDialogBox(3, 0);
|
|
gMenu.transitionTimer = 30;
|
|
SetMenuType(3);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sub_080518E4(void) {
|
|
switch (gMenu.transitionTimer) {
|
|
case 0:
|
|
if (gInput.newKeys & (A_BUTTON | START_BUTTON)) {
|
|
SetFileSelectState(0);
|
|
}
|
|
break;
|
|
default:
|
|
gMenu.transitionTimer--;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void HandleFileStart(void) {
|
|
if (gMenu.menuType == 0) {
|
|
gMenu.menuType = 1;
|
|
gSaveHeader->msg_speed = gSave.msg_speed;
|
|
gSaveHeader->brightness = gSave.brightness;
|
|
gMain.state = GAMETASK_MAIN;
|
|
SetFade(FADE_IN_OUT | FADE_INSTANT, 8);
|
|
}
|
|
}
|
|
|
|
void ResetSaveFile(u32 save_idx) {
|
|
SaveFile* save;
|
|
|
|
gMapDataBottomSpecial.saveStatus[save_idx] = 0;
|
|
save = &gMapDataBottomSpecial.saves[save_idx];
|
|
MemClear(save, sizeof(SaveFile));
|
|
save->msg_speed = 1;
|
|
save->brightness = 1;
|
|
save->stats.health = 24;
|
|
save->stats.maxHealth = 24;
|
|
}
|