diff --git a/graphics/misc/reset_rtc_screen_arrow.pal b/graphics/reset_rtc_screen/arrow.pal similarity index 100% rename from graphics/misc/reset_rtc_screen_arrow.pal rename to graphics/reset_rtc_screen/arrow.pal diff --git a/graphics/misc/reset_rtc_screen_downarrow.png b/graphics/reset_rtc_screen/arrow_down.png similarity index 100% rename from graphics/misc/reset_rtc_screen_downarrow.png rename to graphics/reset_rtc_screen/arrow_down.png diff --git a/graphics/misc/reset_rtc_screen_rightarrow.png b/graphics/reset_rtc_screen/arrow_right.png similarity index 100% rename from graphics/misc/reset_rtc_screen_rightarrow.png rename to graphics/reset_rtc_screen/arrow_right.png diff --git a/include/save.h b/include/save.h index 18b57502b..948530406 100644 --- a/include/save.h +++ b/include/save.h @@ -29,6 +29,11 @@ struct SaveSectionOffsets u16 size; }; +// Each 4 KiB flash sector contains 3968 bytes of actual data followed by a 128 byte footer +#define SECTOR_DATA_SIZE 3968 +#define SECTOR_FOOTER_SIZE 128 +#define SECTOR_SIZE (SECTOR_DATA_SIZE + SECTOR_FOOTER_SIZE) + // Emerald changes this definition to be the sectors per slot. #define NUM_SECTORS_PER_SLOT 16 diff --git a/src/berry_fix_program.c b/src/berry_fix_program.c index 4c4a010b2..31caf79cc 100644 --- a/src/berry_fix_program.c +++ b/src/berry_fix_program.c @@ -12,40 +12,42 @@ #include "text.h" #include "menu.h" #include "m4a.h" +#include "constants/rgb.h" -// Static type declarations - -typedef struct { +struct { u8 state; - u8 unk1; - u16 unk2; + u8 curScene; + u16 timer; struct MultiBootParam mb; -} berryfix_t; +} static * sBerryFix; -// Static RAM declarations - -static berryfix_t *berry_fix_mb_manager; - -// Static ROM declarations - -static void berry_fix_main(void); -static void berry_fix_gpu_set(void); -static int berry_fix_text_update(int); -static void berry_fix_text_print(int); -static void berry_fix_bg_hide(void); - -// .rodata +static void BerryFix_Main(void); +static void BerryFix_GpuSet(void); +static int BerryFix_TrySetScene(int); +static void BerryFix_SetScene(int); +static void BerryFix_HideScene(void); static const u8 sText_BerryProgramUpdate[] = _("Berry Program Update"); static const u8 sText_RubySapphire[] = _("Ruby/Sapphire"); static const u8 sText_Emerald[] = _("Emerald"); - -static const u8 sText_BerryProgramWillBeUpdatedPressA[] = _("The Berry Program on your POKéMON\nRuby/Sapphire Game Pak will be updated.\n{COLOR RED}{SHADOW LIGHT_RED}Press the A Button."); -static const u8 sText_EnsureGBAConnectionMatches[] = _("Please ensure the connection of your\nGame Boy Advance system matches this.\n{COLOR RED}{SHADOW LIGHT_RED}YES: Press the A Button.\nNO: Turn off the power and try again."); -static const u8 sText_TurnOffPowerHoldingStartSelect[] = _("Please turn on the power of POKéMON\nRuby/Sapphire while holding START and\nSELECT simultaneously. Then, ensure\nthe picture above appears."); -static const u8 sText_TransmittingPleaseWait[] = _("Transmitting. Please wait.\n{COLOR RED}{SHADOW LIGHT_RED}Please do not turn off the power or\nunplug the Game Boy Advance Game\nLink Cable."); -static const u8 sText_PleaseFollowInstructionsOnScreen[] = _("Please follow the instructions on your\nPOKéMON Ruby/Sapphire screen."); -static const u8 sText_TransmissionFailureTryAgain[] = _("Transmission failure.\n{COLOR RED}{SHADOW LIGHT_RED}Please try again."); +static const u8 sText_BerryProgramWillBeUpdatedPressA[] = _("The Berry Program on your POKéMON\n" + "Ruby/Sapphire Game Pak will be updated.\n" + "{COLOR RED}{SHADOW LIGHT_RED}Press the A Button."); +static const u8 sText_EnsureGBAConnectionMatches[] = _("Please ensure the connection of your\n" + "Game Boy Advance system matches this.\n" + "{COLOR RED}{SHADOW LIGHT_RED}YES: Press the A Button.\n" + "NO: Turn off the power and try again."); +static const u8 sText_TurnOffPowerHoldingStartSelect[] = _("Please turn on the power of POKéMON\n" + "Ruby/Sapphire while holding START and\n" + "SELECT simultaneously. Then, ensure\n" + "the picture above appears."); +static const u8 sText_TransmittingPleaseWait[] = _("Transmitting. Please wait.\n" + "{COLOR RED}{SHADOW LIGHT_RED}Please do not turn off the power or\n" + "unplug the Game Boy Advance Game\nLink Cable."); +static const u8 sText_PleaseFollowInstructionsOnScreen[] = _("Please follow the instructions on your\n" + "POKéMON Ruby/Sapphire screen."); +static const u8 sText_TransmissionFailureTryAgain[] = _("Transmission failure.\n" + "{COLOR RED}{SHADOW LIGHT_RED}Please try again."); static const struct BgTemplate sBerryFixBgTemplates[] = { { @@ -108,52 +110,66 @@ static const struct WindowTemplate sBerryFixWindowTemplates[] = { DUMMY_WIN_TEMPLATE }; -static const u16 sUnknown_08618138[] = { - 0x7fff, 0x7fff, 0x318c, 0x675a, - 0x043c, 0x3aff, 0x0664, 0x4bd2, - 0x6546, 0x7b14, 0x7fff, 0x318c, - 0x675a, 0, 0, 0 +static const u16 sBerryFixPalColors[] = { + RGB_WHITE, RGB_WHITE, RGB(12, 12, 12), RGB(26, 26, 25), + RGB(28, 1, 1), RGB(31, 23, 14), RGB(4, 19, 1), RGB(18, 30, 18), + RGB(6, 10, 25), RGB(20, 24, 30), RGB_WHITE, RGB(12, 12, 12), + RGB(26, 26, 25), RGB_BLACK, RGB_BLACK, RGB_BLACK }; static const u8 sBerryProgramTextColors[] = {TEXT_DYNAMIC_COLOR_1, TEXT_DYNAMIC_COLOR_2, TEXT_DYNAMIC_COLOR_3}; static const u8 sGameTitleTextColors[] = { TEXT_COLOR_TRANSPARENT, TEXT_DYNAMIC_COLOR_1, TEXT_DYNAMIC_COLOR_4}; -static const u8 *const sBerryProgramTexts[] = { - sText_EnsureGBAConnectionMatches, - sText_TurnOffPowerHoldingStartSelect, - sText_TransmittingPleaseWait, - sText_PleaseFollowInstructionsOnScreen, - sText_TransmissionFailureTryAgain, - sText_BerryProgramWillBeUpdatedPressA +enum { + SCENE_ENSURE_CONNECT, + SCENE_TURN_OFF_POWER, + SCENE_TRANSMITTING, + SCENE_FOLLOW_INSTRUCT, + SCENE_TRANSMIT_FAILED, + SCENE_BEGIN, + SCENE_NONE }; +static const u8 *const sBerryProgramTexts[] = { + [SCENE_ENSURE_CONNECT] = sText_EnsureGBAConnectionMatches, + [SCENE_TURN_OFF_POWER] = sText_TurnOffPowerHoldingStartSelect, + [SCENE_TRANSMITTING] = sText_TransmittingPleaseWait, + [SCENE_FOLLOW_INSTRUCT] = sText_PleaseFollowInstructionsOnScreen, + [SCENE_TRANSMIT_FAILED] = sText_TransmissionFailureTryAgain, + [SCENE_BEGIN] = sText_BerryProgramWillBeUpdatedPressA +}; static const struct { const u32 *gfx; const u32 *tilemap; - const u16 *pltt; + const u16 *palette; } sBerryFixGraphics[] = { - { + [SCENE_ENSURE_CONNECT] = { gBerryFixGameboy_Gfx, gBerryFixGameboy_Tilemap, gBerryFixGameboy_Pal - }, { + }, + [SCENE_TURN_OFF_POWER] = { gBerryFixGameboyLogo_Gfx, gBerryFixGameboyLogo_Tilemap, gBerryFixGameboyLogo_Pal - }, { + }, + [SCENE_TRANSMITTING] = { gBerryFixGbaTransfer_Gfx, gBerryFixGbaTransfer_Tilemap, gBerryFixGbaTransfer_Pal - }, { + }, + [SCENE_FOLLOW_INSTRUCT] = { gBerryFixGbaTransferHighlight_Gfx, gBerryFixGbaTransferHighlight_Tilemap, gBerryFixGbaTransferHighlight_Pal - }, { + }, + [SCENE_TRANSMIT_FAILED] = { gBerryFixGbaTransferError_Gfx, gBerryFixGbaTransferError_Tilemap, gBerryFixGbaTransferError_Pal - }, { + }, + [SCENE_BEGIN] = { gBerryFixWindow_Gfx, gBerryFixWindow_Tilemap, gBerryFixWindow_Pal @@ -163,7 +179,16 @@ static const struct { extern const u8 gMultiBootProgram_BerryGlitchFix_Start[0x3BF4]; extern const u8 gMultiBootProgram_BerryGlitchFix_End[]; -// .text +enum { + MAINSTATE_INIT, + MAINSTATE_BEGIN, + MAINSTATE_CONNECT, + MAINSTATE_INIT_MULTIBOOT, + MAINSTATE_MULTIBOOT, + MAINSTATE_TRANSMIT, + MAINSTATE_EXIT, + MAINSTATE_FAILED, +}; void CB2_InitBerryFixProgram(void) { @@ -175,81 +200,79 @@ void CB2_InitBerryFixProgram(void) ResetTasks(); ScanlineEffect_Stop(); SetGpuReg(REG_OFFSET_DISPCNT, 0); - berry_fix_mb_manager = AllocZeroed(0x50); - berry_fix_mb_manager->state = 0; - berry_fix_mb_manager->unk1 = 6; - SetMainCallback2(berry_fix_main); + sBerryFix = AllocZeroed(sizeof(*sBerryFix)); + sBerryFix->state = MAINSTATE_INIT; + sBerryFix->curScene = SCENE_NONE; + SetMainCallback2(BerryFix_Main); } -static void berry_fix_main(void) +#define TryScene(sceneNum) BerryFix_TrySetScene(sceneNum) == (sceneNum) + +static void BerryFix_Main(void) { - switch (berry_fix_mb_manager->state) + switch (sBerryFix->state) { - case 0: - berry_fix_gpu_set(); - berry_fix_mb_manager->state = 1; + case MAINSTATE_INIT: + BerryFix_GpuSet(); + sBerryFix->state = MAINSTATE_BEGIN; break; - case 1: - if (berry_fix_text_update(5) == 5 && (JOY_NEW(A_BUTTON))) + case MAINSTATE_BEGIN: + if (TryScene(SCENE_BEGIN) && (JOY_NEW(A_BUTTON))) + sBerryFix->state = MAINSTATE_CONNECT; + break; + case MAINSTATE_CONNECT: + if (TryScene(SCENE_ENSURE_CONNECT) && (JOY_NEW(A_BUTTON))) + sBerryFix->state = MAINSTATE_INIT_MULTIBOOT; + break; + case MAINSTATE_INIT_MULTIBOOT: + if (TryScene(SCENE_TURN_OFF_POWER)) { - berry_fix_mb_manager->state = 2; + sBerryFix->mb.masterp = gMultiBootProgram_BerryGlitchFix_Start; + sBerryFix->mb.server_type = 0; + MultiBootInit(&sBerryFix->mb); + sBerryFix->timer = 0; + sBerryFix->state = MAINSTATE_MULTIBOOT; } break; - case 2: - if (berry_fix_text_update(0) == 0 && (JOY_NEW(A_BUTTON))) + case MAINSTATE_MULTIBOOT: + MultiBootMain(&sBerryFix->mb); + if (sBerryFix->mb.probe_count != 0 || (!(sBerryFix->mb.response_bit & 2) || !(sBerryFix->mb.client_bit & 2))) { - berry_fix_mb_manager->state = 3; + sBerryFix->timer = 0; + } + else if (++sBerryFix->timer > 180) + { + MultiBootStartMaster(&sBerryFix->mb, + gMultiBootProgram_BerryGlitchFix_Start + ROM_HEADER_SIZE, + (u32)(gMultiBootProgram_BerryGlitchFix_End - (gMultiBootProgram_BerryGlitchFix_Start + ROM_HEADER_SIZE)), + 4, + 1); + sBerryFix->state = MAINSTATE_TRANSMIT; } break; - case 3: - if (berry_fix_text_update(1) == 1) + case MAINSTATE_TRANSMIT: + if (TryScene(SCENE_TRANSMITTING)) { - berry_fix_mb_manager->mb.masterp = gMultiBootProgram_BerryGlitchFix_Start; - berry_fix_mb_manager->mb.server_type = 0; - MultiBootInit(&berry_fix_mb_manager->mb); - berry_fix_mb_manager->unk2 = 0; - berry_fix_mb_manager->state = 4; + MultiBootMain(&sBerryFix->mb); + + if (MultiBootCheckComplete(&sBerryFix->mb)) + sBerryFix->state = MAINSTATE_EXIT; + else if (!(sBerryFix->mb.client_bit & 2)) + sBerryFix->state = MAINSTATE_FAILED; } break; - case 4: - MultiBootMain(&berry_fix_mb_manager->mb); - if (berry_fix_mb_manager->mb.probe_count != 0 || (!(berry_fix_mb_manager->mb.response_bit & 2) || !(berry_fix_mb_manager->mb.client_bit & 2))) - { - berry_fix_mb_manager->unk2 = 0; - } - else if (++ berry_fix_mb_manager->unk2 > 180) - { - MultiBootStartMaster(&berry_fix_mb_manager->mb, gMultiBootProgram_BerryGlitchFix_Start + ROM_HEADER_SIZE, (u32)(gMultiBootProgram_BerryGlitchFix_End - (gMultiBootProgram_BerryGlitchFix_Start + ROM_HEADER_SIZE)), 4, 1); - berry_fix_mb_manager->state = 5; - } - break; - case 5: - if (berry_fix_text_update(2) == 2) { - MultiBootMain(&berry_fix_mb_manager->mb); - if (MultiBootCheckComplete(&berry_fix_mb_manager->mb)) { - berry_fix_mb_manager->state = 6; - } - else if (!(berry_fix_mb_manager->mb.client_bit & 2)) { - berry_fix_mb_manager->state = 7; - } - } - break; - case 6: - if (berry_fix_text_update(3) == 3 && JOY_NEW(A_BUTTON)) - { + case MAINSTATE_EXIT: + if (TryScene(SCENE_FOLLOW_INSTRUCT) && JOY_NEW(A_BUTTON)) DoSoftReset(); - } break; - case 7: - if (berry_fix_text_update(4) == 4 && JOY_NEW(A_BUTTON)) - { - berry_fix_mb_manager->state = 1; - } + case MAINSTATE_FAILED: + if (TryScene(SCENE_TRANSMIT_FAILED) && JOY_NEW(A_BUTTON)) + sBerryFix->state = MAINSTATE_BEGIN; break; } } -static void berry_fix_gpu_set(void) +static void BerryFix_GpuSet(void) { s32 width, left; @@ -274,26 +297,26 @@ static void berry_fix_gpu_set(void) InitWindows(sBerryFixWindowTemplates); DeactivateAllTextPrinters(); - DmaCopy32(3, sUnknown_08618138, BG_PLTT + 0x1E0, 0x20); + DmaCopy32(3, sBerryFixPalColors, BG_PLTT + 0x1E0, sizeof(sBerryFixPalColors)); SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP); FillWindowPixelBuffer(2, PIXEL_FILL(0)); FillWindowPixelBuffer(3, PIXEL_FILL(0)); - FillWindowPixelBuffer(0, PIXEL_FILL(0xA)); + FillWindowPixelBuffer(0, PIXEL_FILL(10)); width = GetStringWidth(0, sText_Emerald, 0); - left = (0x78 - width) / 2; + left = (120 - width) / 2; AddTextPrinterParameterized3(2, 0, left, 3, sGameTitleTextColors, TEXT_SPEED_FF, sText_Emerald); width = GetStringWidth(0, sText_RubySapphire, 0); - left = (0x78 - width) / 2 + 0x78; + left = (120 - width) / 2 + 120; AddTextPrinterParameterized3(2, 0, left, 3, sGameTitleTextColors, TEXT_SPEED_FF, sText_RubySapphire); width = GetStringWidth(0, sText_RubySapphire, 0); - left = (0x70 - width) / 2; + left = (112 - width) / 2; AddTextPrinterParameterized3(3, 0, left, 0, sGameTitleTextColors, TEXT_SPEED_FF, sText_RubySapphire); width = GetStringWidth(1, sText_BerryProgramUpdate, 0); - left = (0xD0 - width) / 2; + left = (208 - width) / 2; AddTextPrinterParameterized3(0, 1, left, 2, sBerryProgramTextColors, TEXT_SPEED_FF, sText_BerryProgramUpdate); CopyWindowToVram(2, 2); @@ -301,56 +324,55 @@ static void berry_fix_gpu_set(void) CopyWindowToVram(0, 2); } -static int berry_fix_text_update(int checkval) +static int BerryFix_TrySetScene(int scene) { - if (berry_fix_mb_manager->unk1 == checkval) + if (sBerryFix->curScene == scene) + return scene; + + if (sBerryFix->curScene == SCENE_NONE) { - return checkval; - } - if (berry_fix_mb_manager->unk1 == 6) - { - berry_fix_text_print(checkval); - berry_fix_mb_manager->unk1 = checkval; + BerryFix_SetScene(scene); + sBerryFix->curScene = scene; } else { - berry_fix_bg_hide(); - berry_fix_mb_manager->unk1 = 6; + BerryFix_HideScene(); + sBerryFix->curScene = SCENE_NONE; } - return berry_fix_mb_manager->unk1; + return sBerryFix->curScene; } -static void berry_fix_text_print(int scene) +static void BerryFix_SetScene(int scene) { FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 32, 32); - FillWindowPixelBuffer(1, PIXEL_FILL(0xA)); + FillWindowPixelBuffer(1, PIXEL_FILL(10)); AddTextPrinterParameterized3(1, 1, 0, 0, sBerryProgramTextColors, -1, sBerryProgramTexts[scene]); PutWindowTilemap(1); CopyWindowToVram(1, 2); switch (scene) { - case 0: - case 2: - case 3: - case 4: - PutWindowTilemap(2); - break; - case 1: - PutWindowTilemap(3); - break; - case 5: - PutWindowTilemap(0); - break; + case SCENE_ENSURE_CONNECT: + case SCENE_TRANSMITTING: + case SCENE_FOLLOW_INSTRUCT: + case SCENE_TRANSMIT_FAILED: + PutWindowTilemap(2); + break; + case SCENE_TURN_OFF_POWER: + PutWindowTilemap(3); + break; + case SCENE_BEGIN: + PutWindowTilemap(0); + break; } CopyBgTilemapBufferToVram(0); LZ77UnCompVram(sBerryFixGraphics[scene].gfx, (void *)BG_CHAR_ADDR(1)); LZ77UnCompVram(sBerryFixGraphics[scene].tilemap, (void *)BG_SCREEN_ADDR(31)); - CpuCopy32(sBerryFixGraphics[scene].pltt, (void *)BG_PLTT, 0x100); + CpuCopy32(sBerryFixGraphics[scene].palette, (void *)BG_PLTT, 0x100); ShowBg(0); ShowBg(1); } -static void berry_fix_bg_hide(void) +static void BerryFix_HideScene(void) { HideBg(0); HideBg(1); diff --git a/src/reset_rtc_screen.c b/src/reset_rtc_screen.c index 052ca820a..cc4da7e16 100644 --- a/src/reset_rtc_screen.c +++ b/src/reset_rtc_screen.c @@ -19,24 +19,52 @@ #include "gpu_regs.h" #include "constants/rgb.h" -struct ResetRtcStruct +#define PALTAG_ARROW 0x1000 + +// Task data for the Task_ResetRtc_* series of tasks, when setting the time on the clock +// Data from these tasks is also used by the cursors and the main task (Task_ResetRtcScreen) +enum { + DATAIDX_DAYS = 3, + DATAIDX_HOURS, + DATAIDX_MINS, + DATAIDX_SECS, + DATAIDX_CONFIRM, +}; +#define tFinished data[0] +#define tSetTime data[1] +#define tSelection data[2] +#define tDays data[DATAIDX_DAYS] +#define tHours data[DATAIDX_HOURS] +#define tMinutes data[DATAIDX_MINS] +#define tSeconds data[DATAIDX_SECS] +#define tConfirm data[DATAIDX_CONFIRM] +#define tWindowId data[8] + +enum { + SELECTION_DAYS = 1, + SELECTION_HOURS, + SELECTION_MINS, + SELECTION_SECS, + SELECTION_CONFIRM, + SELECTION_NONE +}; + +struct ResetRtcInputMap { /*0x0*/ u8 dataIndex; /*0x2*/ u16 minVal; /*0x4*/ u16 maxVal; /*0x6*/ u8 left; /*0x7*/ u8 right; - /*0x8*/ u8 unk8; + /*0x8*/ u8 unk; // never read }; -// this file's functions static void CB2_ResetRtcScreen(void); static void VBlankCB(void); static void Task_ResetRtcScreen(u8 taskId); -static void sub_809F048(void); +static void InitResetRtcScreenBgAndWindows(void); -// const rom data -static const struct BgTemplate sBackgroundTemplates[] = +static const struct BgTemplate sBgTemplates[] = { { .bg = 0, @@ -49,60 +77,84 @@ static const struct BgTemplate sBackgroundTemplates[] = } }; -static const struct WindowTemplate sUnknown_08510408[] = +static const struct WindowTemplate sWindowTemplates[] = { - {0x00, 0x01, 0x01, 0x13, 0x09, 0x0f, 0x0155}, - {0x00, 0x02, 0x0f, 0x1b, 0x04, 0x0f, 0x00e9}, + { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 1, + .width = 19, + .height = 9, + .paletteNum = 15, + .baseBlock = 0x155 + }, + { + .bg = 0, + .tilemapLeft = 2, + .tilemapTop = 15, + .width = 27, + .height = 4, + .paletteNum = 15, + .baseBlock = 0xE9 + }, DUMMY_WIN_TEMPLATE }; -static const struct WindowTemplate sUnknown_08510420 = {0x00, 0x04, 0x09, 0x15, 0x02, 0x0f, 0x00bf}; +static const struct WindowTemplate sInputTimeWindow = { + .bg = 0, + .tilemapLeft = 4, + .tilemapTop = 9, + .width = 21, + .height = 2, + .paletteNum = 15, + .baseBlock = 0xBF +}; -static const struct ResetRtcStruct sUnknown_08510428[5] = +static const struct ResetRtcInputMap sInputMap[] = { - { - .dataIndex = 3, + [SELECTION_DAYS - 1] = { + .dataIndex = DATAIDX_DAYS, .minVal = 1, .maxVal = 9999, .left = 0, .right = 2, - .unk8 = 0, + .unk = 0, }, - { - .dataIndex = 4, + [SELECTION_HOURS - 1] = { + .dataIndex = DATAIDX_HOURS, .minVal = 0, .maxVal = 23, .left = 1, .right = 3, - .unk8 = 0, + .unk = 0, }, - { - .dataIndex = 5, + [SELECTION_MINS - 1] = { + .dataIndex = DATAIDX_MINS, .minVal = 0, .maxVal = 59, .left = 2, .right = 4, - .unk8 = 0, + .unk = 0, }, - { - .dataIndex = 6, + [SELECTION_SECS - 1] = { + .dataIndex = DATAIDX_SECS, .minVal = 0, .maxVal = 59, .left = 3, .right = 5, - .unk8 = 0, + .unk = 0, }, - { - .dataIndex = 7, + [SELECTION_CONFIRM - 1] = { + .dataIndex = DATAIDX_CONFIRM, .minVal = 0, .maxVal = 0, .left = 4, .right = 0, - .unk8 = 6, + .unk = 6, }, }; -static const struct OamData sOamData_08510464 = +static const struct OamData sOamData_Arrow = { .y = 0, .affineMode = ST_OAM_AFFINE_OFF, @@ -119,148 +171,158 @@ static const struct OamData sOamData_08510464 = .affineParam = 0, }; -static const u8 sResetRtcScreen_DownArrowGfx[] = INCBIN_U8("graphics/misc/reset_rtc_screen_downarrow.4bpp"); -static const u8 sResetRtcScreen_RightArrowGfx[] = INCBIN_U8("graphics/misc/reset_rtc_screen_rightarrow.4bpp"); -static const u16 sResetRtcScreen_ArrowPal[] = INCBIN_U16("graphics/misc/reset_rtc_screen_arrow.gbapal"); +static const u8 sArrowDown_Gfx[] = INCBIN_U8("graphics/reset_rtc_screen/arrow_down.4bpp"); +static const u8 sArrowRight_Gfx[] = INCBIN_U8("graphics/reset_rtc_screen/arrow_right.4bpp"); +static const u16 sArrow_Pal[] = INCBIN_U16("graphics/reset_rtc_screen/arrow.gbapal"); -static const struct SpriteFrameImage sSpriteImageTable_85104B4[] = +static const struct SpriteFrameImage sPicTable_Arrow[] = { - obj_frame_tiles(sResetRtcScreen_DownArrowGfx), - obj_frame_tiles(sResetRtcScreen_RightArrowGfx) + obj_frame_tiles(sArrowDown_Gfx), + obj_frame_tiles(sArrowRight_Gfx) }; static const struct SpritePalette sSpritePalette_Arrow = { - sResetRtcScreen_ArrowPal, 0x1000 + sArrow_Pal, PALTAG_ARROW }; -static const union AnimCmd sSpriteAnim_85104CC[] = +static const union AnimCmd sAnim_Arrow_Down[] = { ANIMCMD_FRAME(0, 30), ANIMCMD_JUMP(0), }; -static const union AnimCmd sSpriteAnim_85104D4[] = +static const union AnimCmd sAnim_Arrow_Up[] = { ANIMCMD_FRAME(0, 30, .vFlip = TRUE), ANIMCMD_JUMP(0), }; -static const union AnimCmd sSpriteAnim_85104DC[] = +static const union AnimCmd sAnim_Arrow_Right[] = { ANIMCMD_FRAME(1, 30), ANIMCMD_JUMP(0), }; -static const union AnimCmd *const sSpriteAnimTable_85104E4[] = -{ - sSpriteAnim_85104CC, - sSpriteAnim_85104D4, - sSpriteAnim_85104DC, +enum { + ARROW_DOWN, + ARROW_UP, + ARROW_RIGHT, }; -static const struct SpriteTemplate sSpriteTemplate_85104F0 = +static const union AnimCmd *const sAnims_Arrow[] = +{ + [ARROW_DOWN] = sAnim_Arrow_Down, + [ARROW_UP] = sAnim_Arrow_Up, + [ARROW_RIGHT] = sAnim_Arrow_Right, +}; + +static const struct SpriteTemplate sSpriteTemplate_Arrow = { .tileTag = 0xFFFF, - .paletteTag = 0x1000, - .oam = &sOamData_08510464, - .anims = sSpriteAnimTable_85104E4, - .images = sSpriteImageTable_85104B4, + .paletteTag = PALTAG_ARROW, + .oam = &sOamData_Arrow, + .anims = sAnims_Arrow, + .images = sPicTable_Arrow, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy, }; -// code -static void SpriteCB_ResetRtcCursor0(struct Sprite *sprite) +#define sTaskId data[0] +#define sState data[1] + +static void SpriteCB_Cursor_UpOrRight(struct Sprite *sprite) { - int state = gTasks[sprite->data[0]].data[2]; - if (state != sprite->data[1]) + int state = gTasks[sprite->sTaskId].tSelection; + if (state != sprite->sState) { - sprite->data[1] = state; + sprite->sState = state; switch (state) { - case 1: + case SELECTION_DAYS: sprite->invisible = FALSE; - sprite->animNum = 1; + sprite->animNum = ARROW_UP; sprite->animDelayCounter = 0; sprite->pos1.x = 53; sprite->pos1.y = 68; break; - case 2: + case SELECTION_HOURS: sprite->invisible = FALSE; - sprite->animNum = 1; + sprite->animNum = ARROW_UP; sprite->animDelayCounter = 0; sprite->pos1.x = 86; sprite->pos1.y = 68; break; - case 3: + case SELECTION_MINS: sprite->invisible = FALSE; - sprite->animNum = 1; + sprite->animNum = ARROW_UP; sprite->animDelayCounter = 0; sprite->pos1.x = 101; sprite->pos1.y = 68; break; - case 4: + case SELECTION_SECS: sprite->invisible = FALSE; - sprite->animNum = 1; + sprite->animNum = ARROW_UP; sprite->animDelayCounter = 0; sprite->pos1.x = 116; sprite->pos1.y = 68; break; - case 5: + case SELECTION_CONFIRM: sprite->invisible = FALSE; - sprite->animNum = 2; + sprite->animNum = ARROW_RIGHT; sprite->animDelayCounter = 0; sprite->pos1.x = 153; sprite->pos1.y = 80; break; - case 6: + case SELECTION_NONE: DestroySprite(sprite); break; } } } -static void SpriteCB_ResetRtcCursor1(struct Sprite *sprite) +static void SpriteCB_Cursor_Down(struct Sprite *sprite) { - int state = gTasks[sprite->data[0]].data[2]; - if (state != sprite->data[1]) + int state = gTasks[sprite->sTaskId].tSelection; + if (state != sprite->sState) { - sprite->data[1] = state; + sprite->sState = state; switch (state) { - case 1: + case SELECTION_DAYS: sprite->invisible = FALSE; - sprite->animNum = 0; + sprite->animNum = ARROW_DOWN; sprite->animDelayCounter = 0; sprite->pos1.x = 53; sprite->pos1.y = 92; break; - case 2: + case SELECTION_HOURS: sprite->invisible = FALSE; - sprite->animNum = 0; + sprite->animNum = ARROW_DOWN; sprite->animDelayCounter = 0; sprite->pos1.x = 86; sprite->pos1.y = 92; break; - case 3: + case SELECTION_MINS: sprite->invisible = FALSE; - sprite->animNum = 0; + sprite->animNum = ARROW_DOWN; sprite->animDelayCounter = 0; sprite->pos1.x = 101; sprite->pos1.y = 92; break; - case 4: + case SELECTION_SECS: sprite->invisible = FALSE; - sprite->animNum = 0; + sprite->animNum = ARROW_DOWN; sprite->animDelayCounter = 0; sprite->pos1.x = 116; sprite->pos1.y = 92; break; - case 5: + case SELECTION_CONFIRM: + // The up arrow is used as a right arrow when Confirm is selected + // Hide the down arrow sprite->invisible = TRUE; break; - case 6: + case SELECTION_NONE: DestroySprite(sprite); break; } @@ -273,15 +335,15 @@ static void CreateCursor(u8 taskId) LoadSpritePalette(&sSpritePalette_Arrow); - spriteId = CreateSpriteAtEnd(&sSpriteTemplate_85104F0, 53, 68, 0); - gSprites[spriteId].callback = SpriteCB_ResetRtcCursor0; - gSprites[spriteId].data[0] = taskId; - gSprites[spriteId].data[1] = -1; + spriteId = CreateSpriteAtEnd(&sSpriteTemplate_Arrow, 53, 68, 0); + gSprites[spriteId].callback = SpriteCB_Cursor_UpOrRight; + gSprites[spriteId].sTaskId = taskId; + gSprites[spriteId].sState = -1; - spriteId = CreateSpriteAtEnd(&sSpriteTemplate_85104F0, 53, 68, 0); - gSprites[spriteId].callback = SpriteCB_ResetRtcCursor1; - gSprites[spriteId].data[0] = taskId; - gSprites[spriteId].data[1] = -1; + spriteId = CreateSpriteAtEnd(&sSpriteTemplate_Arrow, 53, 68, 0); + gSprites[spriteId].callback = SpriteCB_Cursor_Down; + gSprites[spriteId].sTaskId = taskId; + gSprites[spriteId].sState = -1; } static void FreeCursorPalette(void) @@ -300,18 +362,22 @@ static void PrintTime(u8 windowId, u8 x, u8 y, u16 days, u8 hours, u8 minutes, u { u8 *dest = gStringVar4; + // Print days ConvertIntToDecimalStringN(gStringVar1, days, STR_CONV_MODE_RIGHT_ALIGN, 4); dest = StringCopy(dest, gStringVar1); dest = StringCopy(dest, gText_Day); + // Print hours ConvertIntToDecimalStringN(gStringVar1, hours, STR_CONV_MODE_RIGHT_ALIGN, 3); dest = StringCopy(dest, gStringVar1); dest = StringCopy(dest, gText_Colon3); + // Print minutes ConvertIntToDecimalStringN(gStringVar1, minutes, STR_CONV_MODE_LEADING_ZEROS, 2); dest = StringCopy(dest, gStringVar1); dest = StringCopy(dest, gText_Colon3); + // Print seconds ConvertIntToDecimalStringN(gStringVar1, seconds, STR_CONV_MODE_LEADING_ZEROS, 2); dest = StringCopy(dest, gStringVar1); @@ -360,31 +426,31 @@ static bool32 MoveTimeUpDown(s16 *val, int minVal, int maxVal, u16 keys) return TRUE; } -static void Task_ResetRtc_3(u8 taskId) +static void Task_ResetRtc_SetFinished(u8 taskId) { - gTasks[taskId].data[0] = 1; + gTasks[taskId].tFinished = TRUE; } -static void Task_ResetRtc_2(u8 taskId) +static void Task_ResetRtc_Exit(u8 taskId) { s16 *data = gTasks[taskId].data; - HideChooseTimeWindow(data[8]); + HideChooseTimeWindow(tWindowId); FreeCursorPalette(); - gTasks[taskId].func = Task_ResetRtc_3; + gTasks[taskId].func = Task_ResetRtc_SetFinished; } -static void Task_ResetRtc_1(u8 taskId) +static void Task_ResetRtc_HandleInput(u8 taskId) { s16 *data = gTasks[taskId].data; - u8 selection = data[2]; - const struct ResetRtcStruct *selectionInfo = &sUnknown_08510428[selection - 1]; + u8 selection = tSelection; + const struct ResetRtcInputMap *selectionInfo = &sInputMap[selection - 1]; if (JOY_NEW(B_BUTTON)) { - gTasks[taskId].func = Task_ResetRtc_2; - data[1] = 0; - data[2] = 6; + gTasks[taskId].func = Task_ResetRtc_Exit; + tSetTime = FALSE; + tSelection = SELECTION_NONE; PlaySE(SE_SELECT); return; } @@ -393,7 +459,7 @@ static void Task_ResetRtc_1(u8 taskId) { if (selectionInfo->right) { - data[2] = selectionInfo->right; + tSelection = selectionInfo->right; PlaySE(SE_SELECT); return; } @@ -403,47 +469,47 @@ static void Task_ResetRtc_1(u8 taskId) { if (selectionInfo->left) { - data[2] = selectionInfo->left; + tSelection = selectionInfo->left; PlaySE(SE_SELECT); return; } } - if (selection == 5) + if (selection == SELECTION_CONFIRM) { if (JOY_NEW(A_BUTTON)) { - gLocalTime.days = data[3]; - gLocalTime.hours = data[4]; - gLocalTime.minutes = data[5]; - gLocalTime.seconds = data[6]; + gLocalTime.days = tDays; + gLocalTime.hours = tHours; + gLocalTime.minutes = tMinutes; + gLocalTime.seconds = tSeconds; PlaySE(SE_SELECT); - gTasks[taskId].func = Task_ResetRtc_2; - data[1] = 1; - data[2] = 6; + gTasks[taskId].func = Task_ResetRtc_Exit; + tSetTime = TRUE; + tSelection = SELECTION_NONE; } } else if (MoveTimeUpDown(&data[selectionInfo->dataIndex], selectionInfo->minVal, selectionInfo->maxVal, JOY_REPEAT(DPAD_UP | DPAD_DOWN))) { PlaySE(SE_SELECT); - PrintTime(data[8], 0, 1, data[3], data[4], data[5], data[6]); - CopyWindowToVram(data[8], 2); + PrintTime(tWindowId, 0, 1, tDays, tHours, tMinutes, tSeconds); + CopyWindowToVram(tWindowId, 2); } } -static void Task_ResetRtc_0(u8 taskId) +static void Task_ResetRtc_Init(u8 taskId) { s16 *data = gTasks[taskId].data; - data[0] = 0; - data[3] = gLocalTime.days; - data[4] = gLocalTime.hours; - data[5] = gLocalTime.minutes; - data[6] = gLocalTime.seconds; - data[8] = AddWindow(&sUnknown_08510420); - ShowChooseTimeWindow(data[8], data[3], data[4], data[5], data[6]); + tFinished = FALSE; + tDays = gLocalTime.days; + tHours = gLocalTime.hours; + tMinutes = gLocalTime.minutes; + tSeconds = gLocalTime.seconds; + tWindowId = AddWindow(&sInputTimeWindow); + ShowChooseTimeWindow(tWindowId, tDays, tHours, tMinutes, tSeconds); CreateCursor(taskId); - data[2] = 2; - gTasks[taskId].func = Task_ResetRtc_1; + tSelection = SELECTION_HOURS; + gTasks[taskId].func = Task_ResetRtc_HandleInput; } void CB2_InitResetRtcScreen(void) @@ -451,7 +517,7 @@ void CB2_InitResetRtcScreen(void) SetGpuReg(REG_OFFSET_DISPCNT, 0); SetVBlankCallback(NULL); DmaClear16(3, PLTT, PLTT_SIZE); - DmaFillLarge16(3, 0, (u8 *)VRAM, 0x18000, 0x1000); + DmaFillLarge16(3, 0, (u8 *)VRAM, VRAM_SIZE, 0x1000); ResetOamRange(0, 128); LoadOam(); ScanlineEffect_Stop(); @@ -459,21 +525,21 @@ void CB2_InitResetRtcScreen(void) ResetSpriteData(); ResetTasks(); ResetPaletteFade(); - sub_809F048(); + InitResetRtcScreenBgAndWindows(); SetVBlankCallback(VBlankCB); SetMainCallback2(CB2_ResetRtcScreen); CreateTask(Task_ResetRtcScreen, 80); } -static void sub_809F048(void) +static void InitResetRtcScreenBgAndWindows(void) { ClearScheduledBgCopiesToVram(); ResetBgsAndClearDma3BusyFlags(0); - InitBgsFromTemplates(0, sBackgroundTemplates, ARRAY_COUNT(sBackgroundTemplates)); + InitBgsFromTemplates(0, sBgTemplates, ARRAY_COUNT(sBgTemplates)); ScheduleBgCopyTilemapToVram(0); SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); ShowBg(0); - InitWindows(sUnknown_08510408); + InitWindows(sWindowTemplates); DeactivateAllTextPrinters(); LoadMessageBoxAndBorderGfx(); } @@ -501,14 +567,17 @@ static void ShowMessage(const u8 *str) ScheduleBgCopyTilemapToVram(0); } +#define tState data[0] + static void Task_ShowResetRtcPrompt(u8 taskId) { s16 *data = gTasks[taskId].data; - switch (data[0]) + switch (tState) { case 0: DrawStdFrameWithCustomTileAndPalette(0, FALSE, 0x214, 0xE); + AddTextPrinterParameterized(0, 1, gText_PresentTime, 0, 1, TEXT_SPEED_FF, 0); PrintTime( 0, @@ -518,6 +587,7 @@ static void Task_ShowResetRtcPrompt(u8 taskId) gLocalTime.hours, gLocalTime.minutes, gLocalTime.seconds); + AddTextPrinterParameterized(0, 1, gText_PreviousTime, 0, 33, TEXT_SPEED_FF, 0); PrintTime( 0, @@ -527,18 +597,21 @@ static void Task_ShowResetRtcPrompt(u8 taskId) gSaveBlock2Ptr->lastBerryTreeUpdate.hours, gSaveBlock2Ptr->lastBerryTreeUpdate.minutes, gSaveBlock2Ptr->lastBerryTreeUpdate.seconds); + ShowMessage(gText_ResetRTCConfirmCancel); CopyWindowToVram(0, 2); ScheduleBgCopyTilemapToVram(0); - data[0]++; + tState++; case 1: if (JOY_NEW(B_BUTTON)) { + // Cancel, exit without resetting RTC DestroyTask(taskId); DoSoftReset(); } else if (JOY_NEW(A_BUTTON)) { + // Confirm PlaySE(SE_SELECT); DestroyTask(taskId); } @@ -546,53 +619,73 @@ static void Task_ShowResetRtcPrompt(u8 taskId) } } +#undef tState + +// Task states for Task_ResetRtcScreen +enum { + MAINSTATE_FADE_IN, + MAINSTATE_CHECK_SAVE, + MAINSTATE_START_SET_TIME, + MAINSTATE_WAIT_SET_TIME, + MAINSTATE_SAVE, + MAINSTATE_WAIT_EXIT, + MAINSTATE_EXIT, +}; + +#define tState data[0] +#define tSubTaskId data[1] + static void Task_ResetRtcScreen(u8 taskId) { s16 *data = gTasks[taskId].data; - switch (data[0]) + switch (tState) { - case 0: + case MAINSTATE_FADE_IN: BeginNormalPaletteFade(PALETTES_ALL, 1, 0x10, 0, RGB_WHITEALPHA); - data[0] = 1; + tState = MAINSTATE_CHECK_SAVE; break; - case 1: + case MAINSTATE_CHECK_SAVE: if (!gPaletteFade.active) { - if (gSaveFileStatus == SAVE_STATUS_EMPTY || gSaveFileStatus == SAVE_STATUS_CORRUPT) + if (gSaveFileStatus == SAVE_STATUS_EMPTY + || gSaveFileStatus == SAVE_STATUS_CORRUPT) { ShowMessage(gText_NoSaveFileCantSetTime); - data[0] = 5; + tState = MAINSTATE_WAIT_EXIT; } else { RtcCalcLocalTime(); - data[1] = CreateTask(Task_ShowResetRtcPrompt, 80); - data[0] = 2; + tSubTaskId = CreateTask(Task_ShowResetRtcPrompt, 80); + tState = MAINSTATE_START_SET_TIME; } } break; - case 2: - if (gTasks[data[1]].isActive != TRUE) + case MAINSTATE_START_SET_TIME: + // Wait for A or B press on prompt first + if (gTasks[tSubTaskId].isActive != TRUE) { ClearStdWindowAndFrameToTransparent(0, FALSE); ShowMessage(gText_PleaseResetTime); gLocalTime = gSaveBlock2Ptr->lastBerryTreeUpdate; - data[1] = CreateTask(Task_ResetRtc_0, 80); - data[0] = 3; + tSubTaskId = CreateTask(Task_ResetRtc_Init, 80); + tState = MAINSTATE_WAIT_SET_TIME; } break; - case 3: - if (gTasks[data[1]].data[0]) + case MAINSTATE_WAIT_SET_TIME: + if (gTasks[tSubTaskId].tFinished) { - if (!gTasks[data[1]].data[1]) + if (!gTasks[tSubTaskId].tSetTime) { - DestroyTask(data[1]); - data[0] = 2; + // Exited without setting time, return to "Please reset time" + DestroyTask(tSubTaskId); + tState = MAINSTATE_START_SET_TIME; } else { - DestroyTask(data[1]); + // Time has been chosen, reset rtc and save + DestroyTask(tSubTaskId); RtcReset(); RtcCalcLocalTimeOffset( gLocalTime.days, @@ -603,11 +696,11 @@ static void Task_ResetRtcScreen(u8 taskId) VarSet(VAR_DAYS, gLocalTime.days); DisableResetRTC(); ShowMessage(gText_ClockHasBeenReset); - data[0] = 4; + tState = MAINSTATE_SAVE; } } break; - case 4: + case MAINSTATE_SAVE: if (TrySavingData(SAVE_NORMAL) == SAVE_STATUS_OK) { ShowMessage(gText_SaveCompleted); @@ -618,18 +711,20 @@ static void Task_ResetRtcScreen(u8 taskId) ShowMessage(gText_SaveFailed); PlaySE(SE_BOO); } - data[0] = 5; - case 5: + tState = MAINSTATE_WAIT_EXIT; + // fallthrough + case MAINSTATE_WAIT_EXIT: if (JOY_NEW(A_BUTTON)) { BeginNormalPaletteFade(PALETTES_ALL, 1, 0, 0x10, RGB_WHITEALPHA); - data[0] = 6; + tState = MAINSTATE_EXIT; + // fallthrough } else { break; } - case 6: + case MAINSTATE_EXIT: if (!gPaletteFade.active) { DestroyTask(taskId); diff --git a/src/save.c b/src/save.c index 680f33de0..bbf4e7dbe 100644 --- a/src/save.c +++ b/src/save.c @@ -23,10 +23,6 @@ static u8 HandleWriteSector(u16 a1, const struct SaveSectionLocation *location); // Divide save blocks into individual chunks to be written to flash sectors -// Each 4 KiB flash sector contains 3968 bytes of actual data followed by a 128 byte footer -#define SECTOR_DATA_SIZE 3968 -#define SECTOR_FOOTER_SIZE 128 - /* * Sector Layout: * diff --git a/src/save_failed_screen.c b/src/save_failed_screen.c index bf6e4d6fb..facdbdc17 100644 --- a/src/save_failed_screen.c +++ b/src/save_failed_screen.c @@ -25,25 +25,25 @@ extern const u8 gText_SaveCompleteGameCannotContinue[]; extern const u8 gText_SaveCompletePressA[]; extern const u8 gText_GamePlayCannotBeContinued[]; -// gSaveFailedClockInfo enum +// sClockInfo enum enum { CLOCK_RUNNING, DEBUG_TIMER }; -// gSaveFailedWindowIds enum +// sWindowIds enum enum { TEXT_WIN_ID, CLOCK_WIN_ID }; -EWRAM_DATA u16 gSaveFailedType = {0}; -EWRAM_DATA u16 gSaveFailedClockInfo[2] = {0}; -EWRAM_DATA u8 gSaveFailedUnused1[12] = {0}; -EWRAM_DATA u8 gSaveFailedWindowIds[2] = {0}; -EWRAM_DATA u8 gSaveFailedUnused2[4] = {0}; +static EWRAM_DATA u16 sSaveFailedType = {0}; +static EWRAM_DATA u16 sClockInfo[2] = {0}; +static EWRAM_DATA u8 sUnused1[12] = {0}; +static EWRAM_DATA u8 sWindowIds[2] = {0}; +static EWRAM_DATA u8 sUnused2[4] = {0}; static const struct OamData sClockOamData = { @@ -93,20 +93,9 @@ static const struct BgTemplate sBgTemplates[3] = }, }; -static const struct WindowTemplate gUnknown_085EFD94[] = -{ - { - .bg = 255, - .tilemapLeft = 0, - .tilemapTop = 0, - .width = 0, - .height = 0, - .paletteNum = 0, - .baseBlock = 0, - } -}; +static const struct WindowTemplate sDummyWindowTemplate[] = { DUMMY_WIN_TEMPLATE }; -static const struct WindowTemplate gUnknown_085EFD9C[] = +static const struct WindowTemplate sWindowTemplate_Text[] = { { .bg = 0, @@ -119,7 +108,7 @@ static const struct WindowTemplate gUnknown_085EFD9C[] = } }; -static const struct WindowTemplate gUnknown_085EFDA4[] = +static const struct WindowTemplate sWindowTemplate_Clock[] = { { .bg = 0, @@ -157,24 +146,24 @@ static bool8 VerifySectorWipe(u16 sector); static bool8 WipeSectors(u32); // Although this is a general text printer, it's only used in this file. -static void SaveFailedScreenTextPrint(const u8 *text, u8 var1, u8 var2) +static void SaveFailedScreenTextPrint(const u8 *text, u8 x, u8 y) { u8 color[3]; - color[0] = 0; - color[1] = 15; - color[2] = 3; - AddTextPrinterParameterized4(gSaveFailedWindowIds[TEXT_WIN_ID], 1, var1 * 8, var2 * 8 + 1, 0, 0, color, 0, text); + color[0] = TEXT_COLOR_TRANSPARENT; + color[1] = TEXT_DYNAMIC_COLOR_6; + color[2] = TEXT_COLOR_LIGHT_GREY; + AddTextPrinterParameterized4(sWindowIds[TEXT_WIN_ID], 1, x * 8, y * 8 + 1, 0, 0, color, 0, text); } void DoSaveFailedScreen(u8 saveType) { SetMainCallback2(CB2_SaveFailedScreen); - gSaveFailedType = saveType; - gSaveFailedClockInfo[CLOCK_RUNNING] = FALSE; - gSaveFailedClockInfo[DEBUG_TIMER] = 0; - gSaveFailedWindowIds[TEXT_WIN_ID] = 0; - gSaveFailedWindowIds[CLOCK_WIN_ID] = 0; + sSaveFailedType = saveType; + sClockInfo[CLOCK_RUNNING] = FALSE; + sClockInfo[DEBUG_TIMER] = 0; + sWindowIds[TEXT_WIN_ID] = 0; + sWindowIds[CLOCK_WIN_ID] = 0; } static void VBlankCB(void) @@ -210,17 +199,17 @@ static void CB2_SaveFailedScreen(void) LZ77UnCompVram(gBirchHelpGfx, (void *)VRAM); LZ77UnCompVram(gBirchBagTilemap, (void *)(BG_SCREEN_ADDR(14))); LZ77UnCompVram(gBirchGrassTilemap, (void *)(BG_SCREEN_ADDR(15))); - LZ77UnCompVram(sSaveFailedClockGfx, (void *)(VRAM + 0x10020)); + LZ77UnCompVram(sSaveFailedClockGfx, (void *)(OBJ_VRAM0 + 0x20)); ResetBgsAndClearDma3BusyFlags(0); InitBgsFromTemplates(0, sBgTemplates, ARRAY_COUNT(sBgTemplates)); SetBgTilemapBuffer(0, (void *)&gDecompressionBuffer[0x2000]); CpuFill32(0, &gDecompressionBuffer[0x2000], 0x800); LoadBgTiles(0, gTextWindowFrame1_Gfx, 0x120, 0x214); - InitWindows(gUnknown_085EFD94); - gSaveFailedWindowIds[TEXT_WIN_ID] = AddWindowWithoutTileMap(gUnknown_085EFD9C); - SetWindowAttribute(gSaveFailedWindowIds[TEXT_WIN_ID], 7, (u32)&gDecompressionBuffer[0x2800]); - gSaveFailedWindowIds[CLOCK_WIN_ID] = AddWindowWithoutTileMap(gUnknown_085EFDA4); - SetWindowAttribute(gSaveFailedWindowIds[CLOCK_WIN_ID], 7, (u32)&gDecompressionBuffer[0x3D00]); + InitWindows(sDummyWindowTemplate); + sWindowIds[TEXT_WIN_ID] = AddWindowWithoutTileMap(sWindowTemplate_Text); + SetWindowAttribute(sWindowIds[TEXT_WIN_ID], 7, (u32)&gDecompressionBuffer[0x2800]); + sWindowIds[CLOCK_WIN_ID] = AddWindowWithoutTileMap(sWindowTemplate_Clock); + SetWindowAttribute(sWindowIds[CLOCK_WIN_ID], 7, (u32)&gDecompressionBuffer[0x3D00]); DeactivateAllTextPrinters(); ResetSpriteData(); ResetTasks(); @@ -229,12 +218,12 @@ static void CB2_SaveFailedScreen(void) LoadPalette(sSaveFailedClockPal, 0x100, 0x20); LoadPalette(gTextWindowFrame1_Pal, 0xE0, 0x20); LoadPalette(gUnknown_0860F074, 0xF0, 0x20); - DrawStdFrameWithCustomTileAndPalette(gSaveFailedWindowIds[TEXT_WIN_ID], FALSE, 0x214, 0xE); - DrawStdFrameWithCustomTileAndPalette(gSaveFailedWindowIds[CLOCK_WIN_ID], FALSE, 0x214, 0xE); - FillWindowPixelBuffer(gSaveFailedWindowIds[CLOCK_WIN_ID], PIXEL_FILL(1)); // backwards? - FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); - CopyWindowToVram(gSaveFailedWindowIds[CLOCK_WIN_ID], 2); // again? - CopyWindowToVram(gSaveFailedWindowIds[TEXT_WIN_ID], 1); + DrawStdFrameWithCustomTileAndPalette(sWindowIds[TEXT_WIN_ID], FALSE, 0x214, 0xE); + DrawStdFrameWithCustomTileAndPalette(sWindowIds[CLOCK_WIN_ID], FALSE, 0x214, 0xE); + FillWindowPixelBuffer(sWindowIds[CLOCK_WIN_ID], PIXEL_FILL(1)); // backwards? + FillWindowPixelBuffer(sWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); + CopyWindowToVram(sWindowIds[CLOCK_WIN_ID], 2); // again? + CopyWindowToVram(sWindowIds[TEXT_WIN_ID], 1); SaveFailedScreenTextPrint(gText_SaveFailedCheckingBackup, 1, 0); BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK); EnableInterrupts(1); @@ -259,25 +248,25 @@ static void CB2_WipeSave(void) { u8 wipeTries = 0; - gSaveFailedClockInfo[CLOCK_RUNNING] = TRUE; + sClockInfo[CLOCK_RUNNING] = TRUE; while (gDamagedSaveSectors != 0 && wipeTries < 3) { - if (WipeSectors(gDamagedSaveSectors) != FALSE) + if (WipeSectors(gDamagedSaveSectors)) { - FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); + FillWindowPixelBuffer(sWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); SaveFailedScreenTextPrint(gText_BackupMemoryDamaged, 1, 0); SetMainCallback2(CB2_GameplayCannotBeContinued); return; } - FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); + FillWindowPixelBuffer(sWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); SaveFailedScreenTextPrint(gText_CheckCompleted, 1, 0); - HandleSavingData(gSaveFailedType); + HandleSavingData(sSaveFailedType); if (gDamagedSaveSectors != 0) { - FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); + FillWindowPixelBuffer(sWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); SaveFailedScreenTextPrint(gText_SaveFailedCheckingBackup, 1, 0); } @@ -286,12 +275,12 @@ static void CB2_WipeSave(void) if (wipeTries == 3) { - FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); + FillWindowPixelBuffer(sWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); SaveFailedScreenTextPrint(gText_BackupMemoryDamaged, 1, 0); } else { - FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); + FillWindowPixelBuffer(sWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); if (gGameContinueCallback == NULL) SaveFailedScreenTextPrint(gText_SaveCompleteGameCannotContinue, 1, 0); @@ -304,11 +293,11 @@ static void CB2_WipeSave(void) static void CB2_GameplayCannotBeContinued(void) { - gSaveFailedClockInfo[CLOCK_RUNNING] = FALSE; + sClockInfo[CLOCK_RUNNING] = FALSE; if (JOY_NEW(A_BUTTON)) { - FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); + FillWindowPixelBuffer(sWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); SaveFailedScreenTextPrint(gText_GamePlayCannotBeContinued, 1, 0); SetVBlankCallback(VBlankCB); SetMainCallback2(CB2_FadeAndReturnToTitleScreen); @@ -317,7 +306,7 @@ static void CB2_GameplayCannotBeContinued(void) static void CB2_FadeAndReturnToTitleScreen(void) { - gSaveFailedClockInfo[CLOCK_RUNNING] = FALSE; + sClockInfo[CLOCK_RUNNING] = FALSE; if (JOY_NEW(A_BUTTON)) { @@ -351,7 +340,7 @@ static void VBlankCB_UpdateClockGraphics(void) gMain.oamBuffer[0].x = 112; gMain.oamBuffer[0].y = (CLOCK_WIN_TOP + 1) * 8; - if (gSaveFailedClockInfo[CLOCK_RUNNING] != FALSE) + if (sClockInfo[CLOCK_RUNNING]) { gMain.oamBuffer[0].tileNum = sClockFrames[n][0]; gMain.oamBuffer[0].matrixNum = (sClockFrames[n][2] << 4) | (sClockFrames[n][1] << 3); @@ -363,8 +352,8 @@ static void VBlankCB_UpdateClockGraphics(void) CpuFastCopy(gMain.oamBuffer, (void *)OAM, 4); - if (gSaveFailedClockInfo[DEBUG_TIMER]) - gSaveFailedClockInfo[DEBUG_TIMER]--; + if (sClockInfo[DEBUG_TIMER]) + sClockInfo[DEBUG_TIMER]--; } static bool8 VerifySectorWipe(u16 sector) @@ -372,7 +361,7 @@ static bool8 VerifySectorWipe(u16 sector) u32 *ptr = (u32 *)&gSaveDataBuffer; u16 i; - ReadFlash(sector, 0, (u8 *)ptr, 4096); + ReadFlash(sector, 0, (u8 *)ptr, SECTOR_SIZE); for (i = 0; i < 0x400; i++, ptr++) if (*ptr) @@ -388,7 +377,7 @@ static bool8 WipeSector(u16 sector) for (i = 0; failed && i < 130; i++) { - for (j = 0; j < 0x1000; j++) + for (j = 0; j < SECTOR_SIZE; j++) ProgramFlashByte(sector, j, 0); failed = VerifySectorWipe(sector); @@ -401,7 +390,7 @@ static bool8 WipeSectors(u32 sectorBits) { u16 i; - for (i = 0; i < 0x20; i++) + for (i = 0; i < SECTORS_COUNT; i++) if ((sectorBits & (1 << i)) && !WipeSector(i)) sectorBits &= ~(1 << i);