Merge pull request #1345 from GriffinRichards/doc-rtcscreen

Document/clean up some minor screens
This commit is contained in:
huderlem 2021-02-28 10:03:22 -06:00 committed by GitHub
commit 10c77f1bc2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 454 additions and 347 deletions

View File

Before

Width:  |  Height:  |  Size: 113 B

After

Width:  |  Height:  |  Size: 113 B

View File

Before

Width:  |  Height:  |  Size: 110 B

After

Width:  |  Height:  |  Size: 110 B

View File

@ -29,6 +29,11 @@ struct SaveSectionOffsets
u16 size; 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. // Emerald changes this definition to be the sectors per slot.
#define NUM_SECTORS_PER_SLOT 16 #define NUM_SECTORS_PER_SLOT 16

View File

@ -12,40 +12,42 @@
#include "text.h" #include "text.h"
#include "menu.h" #include "menu.h"
#include "m4a.h" #include "m4a.h"
#include "constants/rgb.h"
// Static type declarations struct {
typedef struct {
u8 state; u8 state;
u8 unk1; u8 curScene;
u16 unk2; u16 timer;
struct MultiBootParam mb; struct MultiBootParam mb;
} berryfix_t; } static * sBerryFix;
// Static RAM declarations static void BerryFix_Main(void);
static void BerryFix_GpuSet(void);
static berryfix_t *berry_fix_mb_manager; static int BerryFix_TrySetScene(int);
static void BerryFix_SetScene(int);
// Static ROM declarations static void BerryFix_HideScene(void);
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 const u8 sText_BerryProgramUpdate[] = _("Berry Program Update"); static const u8 sText_BerryProgramUpdate[] = _("Berry Program Update");
static const u8 sText_RubySapphire[] = _("Ruby/Sapphire"); static const u8 sText_RubySapphire[] = _("Ruby/Sapphire");
static const u8 sText_Emerald[] = _("Emerald"); static const u8 sText_Emerald[] = _("Emerald");
static const u8 sText_BerryProgramWillBeUpdatedPressA[] = _("The Berry Program on your POKéMON\n"
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."); "Ruby/Sapphire Game Pak will be updated.\n"
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."); "{COLOR RED}{SHADOW LIGHT_RED}Press the A Button.");
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_EnsureGBAConnectionMatches[] = _("Please ensure the connection of your\n"
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."); "Game Boy Advance system matches this.\n"
static const u8 sText_PleaseFollowInstructionsOnScreen[] = _("Please follow the instructions on your\nPOKéMON Ruby/Sapphire screen."); "{COLOR RED}{SHADOW LIGHT_RED}YES: Press the A Button.\n"
static const u8 sText_TransmissionFailureTryAgain[] = _("Transmission failure.\n{COLOR RED}{SHADOW LIGHT_RED}Please try again."); "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[] = { static const struct BgTemplate sBerryFixBgTemplates[] = {
{ {
@ -108,52 +110,66 @@ static const struct WindowTemplate sBerryFixWindowTemplates[] = {
DUMMY_WIN_TEMPLATE DUMMY_WIN_TEMPLATE
}; };
static const u16 sUnknown_08618138[] = { static const u16 sBerryFixPalColors[] = {
0x7fff, 0x7fff, 0x318c, 0x675a, RGB_WHITE, RGB_WHITE, RGB(12, 12, 12), RGB(26, 26, 25),
0x043c, 0x3aff, 0x0664, 0x4bd2, RGB(28, 1, 1), RGB(31, 23, 14), RGB(4, 19, 1), RGB(18, 30, 18),
0x6546, 0x7b14, 0x7fff, 0x318c, RGB(6, 10, 25), RGB(20, 24, 30), RGB_WHITE, RGB(12, 12, 12),
0x675a, 0, 0, 0 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 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 sGameTitleTextColors[] = { TEXT_COLOR_TRANSPARENT, TEXT_DYNAMIC_COLOR_1, TEXT_DYNAMIC_COLOR_4};
static const u8 *const sBerryProgramTexts[] = { enum {
sText_EnsureGBAConnectionMatches, SCENE_ENSURE_CONNECT,
sText_TurnOffPowerHoldingStartSelect, SCENE_TURN_OFF_POWER,
sText_TransmittingPleaseWait, SCENE_TRANSMITTING,
sText_PleaseFollowInstructionsOnScreen, SCENE_FOLLOW_INSTRUCT,
sText_TransmissionFailureTryAgain, SCENE_TRANSMIT_FAILED,
sText_BerryProgramWillBeUpdatedPressA 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 { static const struct {
const u32 *gfx; const u32 *gfx;
const u32 *tilemap; const u32 *tilemap;
const u16 *pltt; const u16 *palette;
} sBerryFixGraphics[] = { } sBerryFixGraphics[] = {
{ [SCENE_ENSURE_CONNECT] = {
gBerryFixGameboy_Gfx, gBerryFixGameboy_Gfx,
gBerryFixGameboy_Tilemap, gBerryFixGameboy_Tilemap,
gBerryFixGameboy_Pal gBerryFixGameboy_Pal
}, { },
[SCENE_TURN_OFF_POWER] = {
gBerryFixGameboyLogo_Gfx, gBerryFixGameboyLogo_Gfx,
gBerryFixGameboyLogo_Tilemap, gBerryFixGameboyLogo_Tilemap,
gBerryFixGameboyLogo_Pal gBerryFixGameboyLogo_Pal
}, { },
[SCENE_TRANSMITTING] = {
gBerryFixGbaTransfer_Gfx, gBerryFixGbaTransfer_Gfx,
gBerryFixGbaTransfer_Tilemap, gBerryFixGbaTransfer_Tilemap,
gBerryFixGbaTransfer_Pal gBerryFixGbaTransfer_Pal
}, { },
[SCENE_FOLLOW_INSTRUCT] = {
gBerryFixGbaTransferHighlight_Gfx, gBerryFixGbaTransferHighlight_Gfx,
gBerryFixGbaTransferHighlight_Tilemap, gBerryFixGbaTransferHighlight_Tilemap,
gBerryFixGbaTransferHighlight_Pal gBerryFixGbaTransferHighlight_Pal
}, { },
[SCENE_TRANSMIT_FAILED] = {
gBerryFixGbaTransferError_Gfx, gBerryFixGbaTransferError_Gfx,
gBerryFixGbaTransferError_Tilemap, gBerryFixGbaTransferError_Tilemap,
gBerryFixGbaTransferError_Pal gBerryFixGbaTransferError_Pal
}, { },
[SCENE_BEGIN] = {
gBerryFixWindow_Gfx, gBerryFixWindow_Gfx,
gBerryFixWindow_Tilemap, gBerryFixWindow_Tilemap,
gBerryFixWindow_Pal gBerryFixWindow_Pal
@ -163,7 +179,16 @@ static const struct {
extern const u8 gMultiBootProgram_BerryGlitchFix_Start[0x3BF4]; extern const u8 gMultiBootProgram_BerryGlitchFix_Start[0x3BF4];
extern const u8 gMultiBootProgram_BerryGlitchFix_End[]; 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) void CB2_InitBerryFixProgram(void)
{ {
@ -175,81 +200,79 @@ void CB2_InitBerryFixProgram(void)
ResetTasks(); ResetTasks();
ScanlineEffect_Stop(); ScanlineEffect_Stop();
SetGpuReg(REG_OFFSET_DISPCNT, 0); SetGpuReg(REG_OFFSET_DISPCNT, 0);
berry_fix_mb_manager = AllocZeroed(0x50); sBerryFix = AllocZeroed(sizeof(*sBerryFix));
berry_fix_mb_manager->state = 0; sBerryFix->state = MAINSTATE_INIT;
berry_fix_mb_manager->unk1 = 6; sBerryFix->curScene = SCENE_NONE;
SetMainCallback2(berry_fix_main); 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: case MAINSTATE_INIT:
berry_fix_gpu_set(); BerryFix_GpuSet();
berry_fix_mb_manager->state = 1; sBerryFix->state = MAINSTATE_BEGIN;
break; break;
case 1: case MAINSTATE_BEGIN:
if (berry_fix_text_update(5) == 5 && (JOY_NEW(A_BUTTON))) 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; break;
case 2: case MAINSTATE_MULTIBOOT:
if (berry_fix_text_update(0) == 0 && (JOY_NEW(A_BUTTON))) 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; break;
case 3: case MAINSTATE_TRANSMIT:
if (berry_fix_text_update(1) == 1) if (TryScene(SCENE_TRANSMITTING))
{ {
berry_fix_mb_manager->mb.masterp = gMultiBootProgram_BerryGlitchFix_Start; MultiBootMain(&sBerryFix->mb);
berry_fix_mb_manager->mb.server_type = 0;
MultiBootInit(&berry_fix_mb_manager->mb); if (MultiBootCheckComplete(&sBerryFix->mb))
berry_fix_mb_manager->unk2 = 0; sBerryFix->state = MAINSTATE_EXIT;
berry_fix_mb_manager->state = 4; else if (!(sBerryFix->mb.client_bit & 2))
sBerryFix->state = MAINSTATE_FAILED;
} }
break; break;
case 4: case MAINSTATE_EXIT:
MultiBootMain(&berry_fix_mb_manager->mb); if (TryScene(SCENE_FOLLOW_INSTRUCT) && JOY_NEW(A_BUTTON))
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))
{
DoSoftReset(); DoSoftReset();
}
break; break;
case 7: case MAINSTATE_FAILED:
if (berry_fix_text_update(4) == 4 && JOY_NEW(A_BUTTON)) if (TryScene(SCENE_TRANSMIT_FAILED) && JOY_NEW(A_BUTTON))
{ sBerryFix->state = MAINSTATE_BEGIN;
berry_fix_mb_manager->state = 1;
}
break; break;
} }
} }
static void berry_fix_gpu_set(void) static void BerryFix_GpuSet(void)
{ {
s32 width, left; s32 width, left;
@ -274,26 +297,26 @@ static void berry_fix_gpu_set(void)
InitWindows(sBerryFixWindowTemplates); InitWindows(sBerryFixWindowTemplates);
DeactivateAllTextPrinters(); 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); SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP);
FillWindowPixelBuffer(2, PIXEL_FILL(0)); FillWindowPixelBuffer(2, PIXEL_FILL(0));
FillWindowPixelBuffer(3, PIXEL_FILL(0)); FillWindowPixelBuffer(3, PIXEL_FILL(0));
FillWindowPixelBuffer(0, PIXEL_FILL(0xA)); FillWindowPixelBuffer(0, PIXEL_FILL(10));
width = GetStringWidth(0, sText_Emerald, 0); 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); AddTextPrinterParameterized3(2, 0, left, 3, sGameTitleTextColors, TEXT_SPEED_FF, sText_Emerald);
width = GetStringWidth(0, sText_RubySapphire, 0); 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); AddTextPrinterParameterized3(2, 0, left, 3, sGameTitleTextColors, TEXT_SPEED_FF, sText_RubySapphire);
width = GetStringWidth(0, sText_RubySapphire, 0); 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); AddTextPrinterParameterized3(3, 0, left, 0, sGameTitleTextColors, TEXT_SPEED_FF, sText_RubySapphire);
width = GetStringWidth(1, sText_BerryProgramUpdate, 0); 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); AddTextPrinterParameterized3(0, 1, left, 2, sBerryProgramTextColors, TEXT_SPEED_FF, sText_BerryProgramUpdate);
CopyWindowToVram(2, 2); CopyWindowToVram(2, 2);
@ -301,56 +324,55 @@ static void berry_fix_gpu_set(void)
CopyWindowToVram(0, 2); 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; BerryFix_SetScene(scene);
} sBerryFix->curScene = scene;
if (berry_fix_mb_manager->unk1 == 6)
{
berry_fix_text_print(checkval);
berry_fix_mb_manager->unk1 = checkval;
} }
else else
{ {
berry_fix_bg_hide(); BerryFix_HideScene();
berry_fix_mb_manager->unk1 = 6; 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); 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]); AddTextPrinterParameterized3(1, 1, 0, 0, sBerryProgramTextColors, -1, sBerryProgramTexts[scene]);
PutWindowTilemap(1); PutWindowTilemap(1);
CopyWindowToVram(1, 2); CopyWindowToVram(1, 2);
switch (scene) switch (scene)
{ {
case 0: case SCENE_ENSURE_CONNECT:
case 2: case SCENE_TRANSMITTING:
case 3: case SCENE_FOLLOW_INSTRUCT:
case 4: case SCENE_TRANSMIT_FAILED:
PutWindowTilemap(2); PutWindowTilemap(2);
break; break;
case 1: case SCENE_TURN_OFF_POWER:
PutWindowTilemap(3); PutWindowTilemap(3);
break; break;
case 5: case SCENE_BEGIN:
PutWindowTilemap(0); PutWindowTilemap(0);
break; break;
} }
CopyBgTilemapBufferToVram(0); CopyBgTilemapBufferToVram(0);
LZ77UnCompVram(sBerryFixGraphics[scene].gfx, (void *)BG_CHAR_ADDR(1)); LZ77UnCompVram(sBerryFixGraphics[scene].gfx, (void *)BG_CHAR_ADDR(1));
LZ77UnCompVram(sBerryFixGraphics[scene].tilemap, (void *)BG_SCREEN_ADDR(31)); 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(0);
ShowBg(1); ShowBg(1);
} }
static void berry_fix_bg_hide(void) static void BerryFix_HideScene(void)
{ {
HideBg(0); HideBg(0);
HideBg(1); HideBg(1);

View File

@ -19,24 +19,52 @@
#include "gpu_regs.h" #include "gpu_regs.h"
#include "constants/rgb.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; /*0x0*/ u8 dataIndex;
/*0x2*/ u16 minVal; /*0x2*/ u16 minVal;
/*0x4*/ u16 maxVal; /*0x4*/ u16 maxVal;
/*0x6*/ u8 left; /*0x6*/ u8 left;
/*0x7*/ u8 right; /*0x7*/ u8 right;
/*0x8*/ u8 unk8; /*0x8*/ u8 unk; // never read
}; };
// this file's functions
static void CB2_ResetRtcScreen(void); static void CB2_ResetRtcScreen(void);
static void VBlankCB(void); static void VBlankCB(void);
static void Task_ResetRtcScreen(u8 taskId); static void Task_ResetRtcScreen(u8 taskId);
static void sub_809F048(void); static void InitResetRtcScreenBgAndWindows(void);
// const rom data static const struct BgTemplate sBgTemplates[] =
static const struct BgTemplate sBackgroundTemplates[] =
{ {
{ {
.bg = 0, .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 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[] =
{ {
{ [SELECTION_DAYS - 1] = {
.dataIndex = 3, .dataIndex = DATAIDX_DAYS,
.minVal = 1, .minVal = 1,
.maxVal = 9999, .maxVal = 9999,
.left = 0, .left = 0,
.right = 2, .right = 2,
.unk8 = 0, .unk = 0,
}, },
{ [SELECTION_HOURS - 1] = {
.dataIndex = 4, .dataIndex = DATAIDX_HOURS,
.minVal = 0, .minVal = 0,
.maxVal = 23, .maxVal = 23,
.left = 1, .left = 1,
.right = 3, .right = 3,
.unk8 = 0, .unk = 0,
}, },
{ [SELECTION_MINS - 1] = {
.dataIndex = 5, .dataIndex = DATAIDX_MINS,
.minVal = 0, .minVal = 0,
.maxVal = 59, .maxVal = 59,
.left = 2, .left = 2,
.right = 4, .right = 4,
.unk8 = 0, .unk = 0,
}, },
{ [SELECTION_SECS - 1] = {
.dataIndex = 6, .dataIndex = DATAIDX_SECS,
.minVal = 0, .minVal = 0,
.maxVal = 59, .maxVal = 59,
.left = 3, .left = 3,
.right = 5, .right = 5,
.unk8 = 0, .unk = 0,
}, },
{ [SELECTION_CONFIRM - 1] = {
.dataIndex = 7, .dataIndex = DATAIDX_CONFIRM,
.minVal = 0, .minVal = 0,
.maxVal = 0, .maxVal = 0,
.left = 4, .left = 4,
.right = 0, .right = 0,
.unk8 = 6, .unk = 6,
}, },
}; };
static const struct OamData sOamData_08510464 = static const struct OamData sOamData_Arrow =
{ {
.y = 0, .y = 0,
.affineMode = ST_OAM_AFFINE_OFF, .affineMode = ST_OAM_AFFINE_OFF,
@ -119,148 +171,158 @@ static const struct OamData sOamData_08510464 =
.affineParam = 0, .affineParam = 0,
}; };
static const u8 sResetRtcScreen_DownArrowGfx[] = INCBIN_U8("graphics/misc/reset_rtc_screen_downarrow.4bpp"); static const u8 sArrowDown_Gfx[] = INCBIN_U8("graphics/reset_rtc_screen/arrow_down.4bpp");
static const u8 sResetRtcScreen_RightArrowGfx[] = INCBIN_U8("graphics/misc/reset_rtc_screen_rightarrow.4bpp"); static const u8 sArrowRight_Gfx[] = INCBIN_U8("graphics/reset_rtc_screen/arrow_right.4bpp");
static const u16 sResetRtcScreen_ArrowPal[] = INCBIN_U16("graphics/misc/reset_rtc_screen_arrow.gbapal"); 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(sArrowDown_Gfx),
obj_frame_tiles(sResetRtcScreen_RightArrowGfx) obj_frame_tiles(sArrowRight_Gfx)
}; };
static const struct SpritePalette sSpritePalette_Arrow = 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_FRAME(0, 30),
ANIMCMD_JUMP(0), ANIMCMD_JUMP(0),
}; };
static const union AnimCmd sSpriteAnim_85104D4[] = static const union AnimCmd sAnim_Arrow_Up[] =
{ {
ANIMCMD_FRAME(0, 30, .vFlip = TRUE), ANIMCMD_FRAME(0, 30, .vFlip = TRUE),
ANIMCMD_JUMP(0), ANIMCMD_JUMP(0),
}; };
static const union AnimCmd sSpriteAnim_85104DC[] = static const union AnimCmd sAnim_Arrow_Right[] =
{ {
ANIMCMD_FRAME(1, 30), ANIMCMD_FRAME(1, 30),
ANIMCMD_JUMP(0), ANIMCMD_JUMP(0),
}; };
static const union AnimCmd *const sSpriteAnimTable_85104E4[] = enum {
{ ARROW_DOWN,
sSpriteAnim_85104CC, ARROW_UP,
sSpriteAnim_85104D4, ARROW_RIGHT,
sSpriteAnim_85104DC,
}; };
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, .tileTag = 0xFFFF,
.paletteTag = 0x1000, .paletteTag = PALTAG_ARROW,
.oam = &sOamData_08510464, .oam = &sOamData_Arrow,
.anims = sSpriteAnimTable_85104E4, .anims = sAnims_Arrow,
.images = sSpriteImageTable_85104B4, .images = sPicTable_Arrow,
.affineAnims = gDummySpriteAffineAnimTable, .affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy, .callback = SpriteCallbackDummy,
}; };
// code #define sTaskId data[0]
static void SpriteCB_ResetRtcCursor0(struct Sprite *sprite) #define sState data[1]
static void SpriteCB_Cursor_UpOrRight(struct Sprite *sprite)
{ {
int state = gTasks[sprite->data[0]].data[2]; int state = gTasks[sprite->sTaskId].tSelection;
if (state != sprite->data[1]) if (state != sprite->sState)
{ {
sprite->data[1] = state; sprite->sState = state;
switch (state) switch (state)
{ {
case 1: case SELECTION_DAYS:
sprite->invisible = FALSE; sprite->invisible = FALSE;
sprite->animNum = 1; sprite->animNum = ARROW_UP;
sprite->animDelayCounter = 0; sprite->animDelayCounter = 0;
sprite->pos1.x = 53; sprite->pos1.x = 53;
sprite->pos1.y = 68; sprite->pos1.y = 68;
break; break;
case 2: case SELECTION_HOURS:
sprite->invisible = FALSE; sprite->invisible = FALSE;
sprite->animNum = 1; sprite->animNum = ARROW_UP;
sprite->animDelayCounter = 0; sprite->animDelayCounter = 0;
sprite->pos1.x = 86; sprite->pos1.x = 86;
sprite->pos1.y = 68; sprite->pos1.y = 68;
break; break;
case 3: case SELECTION_MINS:
sprite->invisible = FALSE; sprite->invisible = FALSE;
sprite->animNum = 1; sprite->animNum = ARROW_UP;
sprite->animDelayCounter = 0; sprite->animDelayCounter = 0;
sprite->pos1.x = 101; sprite->pos1.x = 101;
sprite->pos1.y = 68; sprite->pos1.y = 68;
break; break;
case 4: case SELECTION_SECS:
sprite->invisible = FALSE; sprite->invisible = FALSE;
sprite->animNum = 1; sprite->animNum = ARROW_UP;
sprite->animDelayCounter = 0; sprite->animDelayCounter = 0;
sprite->pos1.x = 116; sprite->pos1.x = 116;
sprite->pos1.y = 68; sprite->pos1.y = 68;
break; break;
case 5: case SELECTION_CONFIRM:
sprite->invisible = FALSE; sprite->invisible = FALSE;
sprite->animNum = 2; sprite->animNum = ARROW_RIGHT;
sprite->animDelayCounter = 0; sprite->animDelayCounter = 0;
sprite->pos1.x = 153; sprite->pos1.x = 153;
sprite->pos1.y = 80; sprite->pos1.y = 80;
break; break;
case 6: case SELECTION_NONE:
DestroySprite(sprite); DestroySprite(sprite);
break; break;
} }
} }
} }
static void SpriteCB_ResetRtcCursor1(struct Sprite *sprite) static void SpriteCB_Cursor_Down(struct Sprite *sprite)
{ {
int state = gTasks[sprite->data[0]].data[2]; int state = gTasks[sprite->sTaskId].tSelection;
if (state != sprite->data[1]) if (state != sprite->sState)
{ {
sprite->data[1] = state; sprite->sState = state;
switch (state) switch (state)
{ {
case 1: case SELECTION_DAYS:
sprite->invisible = FALSE; sprite->invisible = FALSE;
sprite->animNum = 0; sprite->animNum = ARROW_DOWN;
sprite->animDelayCounter = 0; sprite->animDelayCounter = 0;
sprite->pos1.x = 53; sprite->pos1.x = 53;
sprite->pos1.y = 92; sprite->pos1.y = 92;
break; break;
case 2: case SELECTION_HOURS:
sprite->invisible = FALSE; sprite->invisible = FALSE;
sprite->animNum = 0; sprite->animNum = ARROW_DOWN;
sprite->animDelayCounter = 0; sprite->animDelayCounter = 0;
sprite->pos1.x = 86; sprite->pos1.x = 86;
sprite->pos1.y = 92; sprite->pos1.y = 92;
break; break;
case 3: case SELECTION_MINS:
sprite->invisible = FALSE; sprite->invisible = FALSE;
sprite->animNum = 0; sprite->animNum = ARROW_DOWN;
sprite->animDelayCounter = 0; sprite->animDelayCounter = 0;
sprite->pos1.x = 101; sprite->pos1.x = 101;
sprite->pos1.y = 92; sprite->pos1.y = 92;
break; break;
case 4: case SELECTION_SECS:
sprite->invisible = FALSE; sprite->invisible = FALSE;
sprite->animNum = 0; sprite->animNum = ARROW_DOWN;
sprite->animDelayCounter = 0; sprite->animDelayCounter = 0;
sprite->pos1.x = 116; sprite->pos1.x = 116;
sprite->pos1.y = 92; sprite->pos1.y = 92;
break; 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; sprite->invisible = TRUE;
break; break;
case 6: case SELECTION_NONE:
DestroySprite(sprite); DestroySprite(sprite);
break; break;
} }
@ -273,15 +335,15 @@ static void CreateCursor(u8 taskId)
LoadSpritePalette(&sSpritePalette_Arrow); LoadSpritePalette(&sSpritePalette_Arrow);
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_85104F0, 53, 68, 0); spriteId = CreateSpriteAtEnd(&sSpriteTemplate_Arrow, 53, 68, 0);
gSprites[spriteId].callback = SpriteCB_ResetRtcCursor0; gSprites[spriteId].callback = SpriteCB_Cursor_UpOrRight;
gSprites[spriteId].data[0] = taskId; gSprites[spriteId].sTaskId = taskId;
gSprites[spriteId].data[1] = -1; gSprites[spriteId].sState = -1;
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_85104F0, 53, 68, 0); spriteId = CreateSpriteAtEnd(&sSpriteTemplate_Arrow, 53, 68, 0);
gSprites[spriteId].callback = SpriteCB_ResetRtcCursor1; gSprites[spriteId].callback = SpriteCB_Cursor_Down;
gSprites[spriteId].data[0] = taskId; gSprites[spriteId].sTaskId = taskId;
gSprites[spriteId].data[1] = -1; gSprites[spriteId].sState = -1;
} }
static void FreeCursorPalette(void) 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; u8 *dest = gStringVar4;
// Print days
ConvertIntToDecimalStringN(gStringVar1, days, STR_CONV_MODE_RIGHT_ALIGN, 4); ConvertIntToDecimalStringN(gStringVar1, days, STR_CONV_MODE_RIGHT_ALIGN, 4);
dest = StringCopy(dest, gStringVar1); dest = StringCopy(dest, gStringVar1);
dest = StringCopy(dest, gText_Day); dest = StringCopy(dest, gText_Day);
// Print hours
ConvertIntToDecimalStringN(gStringVar1, hours, STR_CONV_MODE_RIGHT_ALIGN, 3); ConvertIntToDecimalStringN(gStringVar1, hours, STR_CONV_MODE_RIGHT_ALIGN, 3);
dest = StringCopy(dest, gStringVar1); dest = StringCopy(dest, gStringVar1);
dest = StringCopy(dest, gText_Colon3); dest = StringCopy(dest, gText_Colon3);
// Print minutes
ConvertIntToDecimalStringN(gStringVar1, minutes, STR_CONV_MODE_LEADING_ZEROS, 2); ConvertIntToDecimalStringN(gStringVar1, minutes, STR_CONV_MODE_LEADING_ZEROS, 2);
dest = StringCopy(dest, gStringVar1); dest = StringCopy(dest, gStringVar1);
dest = StringCopy(dest, gText_Colon3); dest = StringCopy(dest, gText_Colon3);
// Print seconds
ConvertIntToDecimalStringN(gStringVar1, seconds, STR_CONV_MODE_LEADING_ZEROS, 2); ConvertIntToDecimalStringN(gStringVar1, seconds, STR_CONV_MODE_LEADING_ZEROS, 2);
dest = StringCopy(dest, gStringVar1); dest = StringCopy(dest, gStringVar1);
@ -360,31 +426,31 @@ static bool32 MoveTimeUpDown(s16 *val, int minVal, int maxVal, u16 keys)
return TRUE; 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; s16 *data = gTasks[taskId].data;
HideChooseTimeWindow(data[8]); HideChooseTimeWindow(tWindowId);
FreeCursorPalette(); 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; s16 *data = gTasks[taskId].data;
u8 selection = data[2]; u8 selection = tSelection;
const struct ResetRtcStruct *selectionInfo = &sUnknown_08510428[selection - 1]; const struct ResetRtcInputMap *selectionInfo = &sInputMap[selection - 1];
if (JOY_NEW(B_BUTTON)) if (JOY_NEW(B_BUTTON))
{ {
gTasks[taskId].func = Task_ResetRtc_2; gTasks[taskId].func = Task_ResetRtc_Exit;
data[1] = 0; tSetTime = FALSE;
data[2] = 6; tSelection = SELECTION_NONE;
PlaySE(SE_SELECT); PlaySE(SE_SELECT);
return; return;
} }
@ -393,7 +459,7 @@ static void Task_ResetRtc_1(u8 taskId)
{ {
if (selectionInfo->right) if (selectionInfo->right)
{ {
data[2] = selectionInfo->right; tSelection = selectionInfo->right;
PlaySE(SE_SELECT); PlaySE(SE_SELECT);
return; return;
} }
@ -403,47 +469,47 @@ static void Task_ResetRtc_1(u8 taskId)
{ {
if (selectionInfo->left) if (selectionInfo->left)
{ {
data[2] = selectionInfo->left; tSelection = selectionInfo->left;
PlaySE(SE_SELECT); PlaySE(SE_SELECT);
return; return;
} }
} }
if (selection == 5) if (selection == SELECTION_CONFIRM)
{ {
if (JOY_NEW(A_BUTTON)) if (JOY_NEW(A_BUTTON))
{ {
gLocalTime.days = data[3]; gLocalTime.days = tDays;
gLocalTime.hours = data[4]; gLocalTime.hours = tHours;
gLocalTime.minutes = data[5]; gLocalTime.minutes = tMinutes;
gLocalTime.seconds = data[6]; gLocalTime.seconds = tSeconds;
PlaySE(SE_SELECT); PlaySE(SE_SELECT);
gTasks[taskId].func = Task_ResetRtc_2; gTasks[taskId].func = Task_ResetRtc_Exit;
data[1] = 1; tSetTime = TRUE;
data[2] = 6; tSelection = SELECTION_NONE;
} }
} }
else if (MoveTimeUpDown(&data[selectionInfo->dataIndex], selectionInfo->minVal, selectionInfo->maxVal, JOY_REPEAT(DPAD_UP | DPAD_DOWN))) else if (MoveTimeUpDown(&data[selectionInfo->dataIndex], selectionInfo->minVal, selectionInfo->maxVal, JOY_REPEAT(DPAD_UP | DPAD_DOWN)))
{ {
PlaySE(SE_SELECT); PlaySE(SE_SELECT);
PrintTime(data[8], 0, 1, data[3], data[4], data[5], data[6]); PrintTime(tWindowId, 0, 1, tDays, tHours, tMinutes, tSeconds);
CopyWindowToVram(data[8], 2); CopyWindowToVram(tWindowId, 2);
} }
} }
static void Task_ResetRtc_0(u8 taskId) static void Task_ResetRtc_Init(u8 taskId)
{ {
s16 *data = gTasks[taskId].data; s16 *data = gTasks[taskId].data;
data[0] = 0; tFinished = FALSE;
data[3] = gLocalTime.days; tDays = gLocalTime.days;
data[4] = gLocalTime.hours; tHours = gLocalTime.hours;
data[5] = gLocalTime.minutes; tMinutes = gLocalTime.minutes;
data[6] = gLocalTime.seconds; tSeconds = gLocalTime.seconds;
data[8] = AddWindow(&sUnknown_08510420); tWindowId = AddWindow(&sInputTimeWindow);
ShowChooseTimeWindow(data[8], data[3], data[4], data[5], data[6]); ShowChooseTimeWindow(tWindowId, tDays, tHours, tMinutes, tSeconds);
CreateCursor(taskId); CreateCursor(taskId);
data[2] = 2; tSelection = SELECTION_HOURS;
gTasks[taskId].func = Task_ResetRtc_1; gTasks[taskId].func = Task_ResetRtc_HandleInput;
} }
void CB2_InitResetRtcScreen(void) void CB2_InitResetRtcScreen(void)
@ -451,7 +517,7 @@ void CB2_InitResetRtcScreen(void)
SetGpuReg(REG_OFFSET_DISPCNT, 0); SetGpuReg(REG_OFFSET_DISPCNT, 0);
SetVBlankCallback(NULL); SetVBlankCallback(NULL);
DmaClear16(3, PLTT, PLTT_SIZE); DmaClear16(3, PLTT, PLTT_SIZE);
DmaFillLarge16(3, 0, (u8 *)VRAM, 0x18000, 0x1000); DmaFillLarge16(3, 0, (u8 *)VRAM, VRAM_SIZE, 0x1000);
ResetOamRange(0, 128); ResetOamRange(0, 128);
LoadOam(); LoadOam();
ScanlineEffect_Stop(); ScanlineEffect_Stop();
@ -459,21 +525,21 @@ void CB2_InitResetRtcScreen(void)
ResetSpriteData(); ResetSpriteData();
ResetTasks(); ResetTasks();
ResetPaletteFade(); ResetPaletteFade();
sub_809F048(); InitResetRtcScreenBgAndWindows();
SetVBlankCallback(VBlankCB); SetVBlankCallback(VBlankCB);
SetMainCallback2(CB2_ResetRtcScreen); SetMainCallback2(CB2_ResetRtcScreen);
CreateTask(Task_ResetRtcScreen, 80); CreateTask(Task_ResetRtcScreen, 80);
} }
static void sub_809F048(void) static void InitResetRtcScreenBgAndWindows(void)
{ {
ClearScheduledBgCopiesToVram(); ClearScheduledBgCopiesToVram();
ResetBgsAndClearDma3BusyFlags(0); ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, sBackgroundTemplates, ARRAY_COUNT(sBackgroundTemplates)); InitBgsFromTemplates(0, sBgTemplates, ARRAY_COUNT(sBgTemplates));
ScheduleBgCopyTilemapToVram(0); ScheduleBgCopyTilemapToVram(0);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
ShowBg(0); ShowBg(0);
InitWindows(sUnknown_08510408); InitWindows(sWindowTemplates);
DeactivateAllTextPrinters(); DeactivateAllTextPrinters();
LoadMessageBoxAndBorderGfx(); LoadMessageBoxAndBorderGfx();
} }
@ -501,14 +567,17 @@ static void ShowMessage(const u8 *str)
ScheduleBgCopyTilemapToVram(0); ScheduleBgCopyTilemapToVram(0);
} }
#define tState data[0]
static void Task_ShowResetRtcPrompt(u8 taskId) static void Task_ShowResetRtcPrompt(u8 taskId)
{ {
s16 *data = gTasks[taskId].data; s16 *data = gTasks[taskId].data;
switch (data[0]) switch (tState)
{ {
case 0: case 0:
DrawStdFrameWithCustomTileAndPalette(0, FALSE, 0x214, 0xE); DrawStdFrameWithCustomTileAndPalette(0, FALSE, 0x214, 0xE);
AddTextPrinterParameterized(0, 1, gText_PresentTime, 0, 1, TEXT_SPEED_FF, 0); AddTextPrinterParameterized(0, 1, gText_PresentTime, 0, 1, TEXT_SPEED_FF, 0);
PrintTime( PrintTime(
0, 0,
@ -518,6 +587,7 @@ static void Task_ShowResetRtcPrompt(u8 taskId)
gLocalTime.hours, gLocalTime.hours,
gLocalTime.minutes, gLocalTime.minutes,
gLocalTime.seconds); gLocalTime.seconds);
AddTextPrinterParameterized(0, 1, gText_PreviousTime, 0, 33, TEXT_SPEED_FF, 0); AddTextPrinterParameterized(0, 1, gText_PreviousTime, 0, 33, TEXT_SPEED_FF, 0);
PrintTime( PrintTime(
0, 0,
@ -527,18 +597,21 @@ static void Task_ShowResetRtcPrompt(u8 taskId)
gSaveBlock2Ptr->lastBerryTreeUpdate.hours, gSaveBlock2Ptr->lastBerryTreeUpdate.hours,
gSaveBlock2Ptr->lastBerryTreeUpdate.minutes, gSaveBlock2Ptr->lastBerryTreeUpdate.minutes,
gSaveBlock2Ptr->lastBerryTreeUpdate.seconds); gSaveBlock2Ptr->lastBerryTreeUpdate.seconds);
ShowMessage(gText_ResetRTCConfirmCancel); ShowMessage(gText_ResetRTCConfirmCancel);
CopyWindowToVram(0, 2); CopyWindowToVram(0, 2);
ScheduleBgCopyTilemapToVram(0); ScheduleBgCopyTilemapToVram(0);
data[0]++; tState++;
case 1: case 1:
if (JOY_NEW(B_BUTTON)) if (JOY_NEW(B_BUTTON))
{ {
// Cancel, exit without resetting RTC
DestroyTask(taskId); DestroyTask(taskId);
DoSoftReset(); DoSoftReset();
} }
else if (JOY_NEW(A_BUTTON)) else if (JOY_NEW(A_BUTTON))
{ {
// Confirm
PlaySE(SE_SELECT); PlaySE(SE_SELECT);
DestroyTask(taskId); 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) static void Task_ResetRtcScreen(u8 taskId)
{ {
s16 *data = gTasks[taskId].data; s16 *data = gTasks[taskId].data;
switch (data[0]) switch (tState)
{ {
case 0: case MAINSTATE_FADE_IN:
BeginNormalPaletteFade(PALETTES_ALL, 1, 0x10, 0, RGB_WHITEALPHA); BeginNormalPaletteFade(PALETTES_ALL, 1, 0x10, 0, RGB_WHITEALPHA);
data[0] = 1; tState = MAINSTATE_CHECK_SAVE;
break; break;
case 1: case MAINSTATE_CHECK_SAVE:
if (!gPaletteFade.active) if (!gPaletteFade.active)
{ {
if (gSaveFileStatus == SAVE_STATUS_EMPTY || gSaveFileStatus == SAVE_STATUS_CORRUPT) if (gSaveFileStatus == SAVE_STATUS_EMPTY
|| gSaveFileStatus == SAVE_STATUS_CORRUPT)
{ {
ShowMessage(gText_NoSaveFileCantSetTime); ShowMessage(gText_NoSaveFileCantSetTime);
data[0] = 5; tState = MAINSTATE_WAIT_EXIT;
} }
else else
{ {
RtcCalcLocalTime(); RtcCalcLocalTime();
data[1] = CreateTask(Task_ShowResetRtcPrompt, 80); tSubTaskId = CreateTask(Task_ShowResetRtcPrompt, 80);
data[0] = 2; tState = MAINSTATE_START_SET_TIME;
} }
} }
break; break;
case 2: case MAINSTATE_START_SET_TIME:
if (gTasks[data[1]].isActive != TRUE) // Wait for A or B press on prompt first
if (gTasks[tSubTaskId].isActive != TRUE)
{ {
ClearStdWindowAndFrameToTransparent(0, FALSE); ClearStdWindowAndFrameToTransparent(0, FALSE);
ShowMessage(gText_PleaseResetTime); ShowMessage(gText_PleaseResetTime);
gLocalTime = gSaveBlock2Ptr->lastBerryTreeUpdate; gLocalTime = gSaveBlock2Ptr->lastBerryTreeUpdate;
data[1] = CreateTask(Task_ResetRtc_0, 80); tSubTaskId = CreateTask(Task_ResetRtc_Init, 80);
data[0] = 3; tState = MAINSTATE_WAIT_SET_TIME;
} }
break; break;
case 3: case MAINSTATE_WAIT_SET_TIME:
if (gTasks[data[1]].data[0]) if (gTasks[tSubTaskId].tFinished)
{ {
if (!gTasks[data[1]].data[1]) if (!gTasks[tSubTaskId].tSetTime)
{ {
DestroyTask(data[1]); // Exited without setting time, return to "Please reset time"
data[0] = 2; DestroyTask(tSubTaskId);
tState = MAINSTATE_START_SET_TIME;
} }
else else
{ {
DestroyTask(data[1]); // Time has been chosen, reset rtc and save
DestroyTask(tSubTaskId);
RtcReset(); RtcReset();
RtcCalcLocalTimeOffset( RtcCalcLocalTimeOffset(
gLocalTime.days, gLocalTime.days,
@ -603,11 +696,11 @@ static void Task_ResetRtcScreen(u8 taskId)
VarSet(VAR_DAYS, gLocalTime.days); VarSet(VAR_DAYS, gLocalTime.days);
DisableResetRTC(); DisableResetRTC();
ShowMessage(gText_ClockHasBeenReset); ShowMessage(gText_ClockHasBeenReset);
data[0] = 4; tState = MAINSTATE_SAVE;
} }
} }
break; break;
case 4: case MAINSTATE_SAVE:
if (TrySavingData(SAVE_NORMAL) == SAVE_STATUS_OK) if (TrySavingData(SAVE_NORMAL) == SAVE_STATUS_OK)
{ {
ShowMessage(gText_SaveCompleted); ShowMessage(gText_SaveCompleted);
@ -618,18 +711,20 @@ static void Task_ResetRtcScreen(u8 taskId)
ShowMessage(gText_SaveFailed); ShowMessage(gText_SaveFailed);
PlaySE(SE_BOO); PlaySE(SE_BOO);
} }
data[0] = 5; tState = MAINSTATE_WAIT_EXIT;
case 5: // fallthrough
case MAINSTATE_WAIT_EXIT:
if (JOY_NEW(A_BUTTON)) if (JOY_NEW(A_BUTTON))
{ {
BeginNormalPaletteFade(PALETTES_ALL, 1, 0, 0x10, RGB_WHITEALPHA); BeginNormalPaletteFade(PALETTES_ALL, 1, 0, 0x10, RGB_WHITEALPHA);
data[0] = 6; tState = MAINSTATE_EXIT;
// fallthrough
} }
else else
{ {
break; break;
} }
case 6: case MAINSTATE_EXIT:
if (!gPaletteFade.active) if (!gPaletteFade.active)
{ {
DestroyTask(taskId); DestroyTask(taskId);

View File

@ -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 // 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: * Sector Layout:
* *

View File

@ -25,25 +25,25 @@ extern const u8 gText_SaveCompleteGameCannotContinue[];
extern const u8 gText_SaveCompletePressA[]; extern const u8 gText_SaveCompletePressA[];
extern const u8 gText_GamePlayCannotBeContinued[]; extern const u8 gText_GamePlayCannotBeContinued[];
// gSaveFailedClockInfo enum // sClockInfo enum
enum enum
{ {
CLOCK_RUNNING, CLOCK_RUNNING,
DEBUG_TIMER DEBUG_TIMER
}; };
// gSaveFailedWindowIds enum // sWindowIds enum
enum enum
{ {
TEXT_WIN_ID, TEXT_WIN_ID,
CLOCK_WIN_ID CLOCK_WIN_ID
}; };
EWRAM_DATA u16 gSaveFailedType = {0}; static EWRAM_DATA u16 sSaveFailedType = {0};
EWRAM_DATA u16 gSaveFailedClockInfo[2] = {0}; static EWRAM_DATA u16 sClockInfo[2] = {0};
EWRAM_DATA u8 gSaveFailedUnused1[12] = {0}; static EWRAM_DATA u8 sUnused1[12] = {0};
EWRAM_DATA u8 gSaveFailedWindowIds[2] = {0}; static EWRAM_DATA u8 sWindowIds[2] = {0};
EWRAM_DATA u8 gSaveFailedUnused2[4] = {0}; static EWRAM_DATA u8 sUnused2[4] = {0};
static const struct OamData sClockOamData = static const struct OamData sClockOamData =
{ {
@ -93,20 +93,9 @@ static const struct BgTemplate sBgTemplates[3] =
}, },
}; };
static const struct WindowTemplate gUnknown_085EFD94[] = static const struct WindowTemplate sDummyWindowTemplate[] = { DUMMY_WIN_TEMPLATE };
{
{
.bg = 255,
.tilemapLeft = 0,
.tilemapTop = 0,
.width = 0,
.height = 0,
.paletteNum = 0,
.baseBlock = 0,
}
};
static const struct WindowTemplate gUnknown_085EFD9C[] = static const struct WindowTemplate sWindowTemplate_Text[] =
{ {
{ {
.bg = 0, .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, .bg = 0,
@ -157,24 +146,24 @@ static bool8 VerifySectorWipe(u16 sector);
static bool8 WipeSectors(u32); static bool8 WipeSectors(u32);
// Although this is a general text printer, it's only used in this file. // 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]; u8 color[3];
color[0] = 0; color[0] = TEXT_COLOR_TRANSPARENT;
color[1] = 15; color[1] = TEXT_DYNAMIC_COLOR_6;
color[2] = 3; color[2] = TEXT_COLOR_LIGHT_GREY;
AddTextPrinterParameterized4(gSaveFailedWindowIds[TEXT_WIN_ID], 1, var1 * 8, var2 * 8 + 1, 0, 0, color, 0, text); AddTextPrinterParameterized4(sWindowIds[TEXT_WIN_ID], 1, x * 8, y * 8 + 1, 0, 0, color, 0, text);
} }
void DoSaveFailedScreen(u8 saveType) void DoSaveFailedScreen(u8 saveType)
{ {
SetMainCallback2(CB2_SaveFailedScreen); SetMainCallback2(CB2_SaveFailedScreen);
gSaveFailedType = saveType; sSaveFailedType = saveType;
gSaveFailedClockInfo[CLOCK_RUNNING] = FALSE; sClockInfo[CLOCK_RUNNING] = FALSE;
gSaveFailedClockInfo[DEBUG_TIMER] = 0; sClockInfo[DEBUG_TIMER] = 0;
gSaveFailedWindowIds[TEXT_WIN_ID] = 0; sWindowIds[TEXT_WIN_ID] = 0;
gSaveFailedWindowIds[CLOCK_WIN_ID] = 0; sWindowIds[CLOCK_WIN_ID] = 0;
} }
static void VBlankCB(void) static void VBlankCB(void)
@ -210,17 +199,17 @@ static void CB2_SaveFailedScreen(void)
LZ77UnCompVram(gBirchHelpGfx, (void *)VRAM); LZ77UnCompVram(gBirchHelpGfx, (void *)VRAM);
LZ77UnCompVram(gBirchBagTilemap, (void *)(BG_SCREEN_ADDR(14))); LZ77UnCompVram(gBirchBagTilemap, (void *)(BG_SCREEN_ADDR(14)));
LZ77UnCompVram(gBirchGrassTilemap, (void *)(BG_SCREEN_ADDR(15))); LZ77UnCompVram(gBirchGrassTilemap, (void *)(BG_SCREEN_ADDR(15)));
LZ77UnCompVram(sSaveFailedClockGfx, (void *)(VRAM + 0x10020)); LZ77UnCompVram(sSaveFailedClockGfx, (void *)(OBJ_VRAM0 + 0x20));
ResetBgsAndClearDma3BusyFlags(0); ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, sBgTemplates, ARRAY_COUNT(sBgTemplates)); InitBgsFromTemplates(0, sBgTemplates, ARRAY_COUNT(sBgTemplates));
SetBgTilemapBuffer(0, (void *)&gDecompressionBuffer[0x2000]); SetBgTilemapBuffer(0, (void *)&gDecompressionBuffer[0x2000]);
CpuFill32(0, &gDecompressionBuffer[0x2000], 0x800); CpuFill32(0, &gDecompressionBuffer[0x2000], 0x800);
LoadBgTiles(0, gTextWindowFrame1_Gfx, 0x120, 0x214); LoadBgTiles(0, gTextWindowFrame1_Gfx, 0x120, 0x214);
InitWindows(gUnknown_085EFD94); InitWindows(sDummyWindowTemplate);
gSaveFailedWindowIds[TEXT_WIN_ID] = AddWindowWithoutTileMap(gUnknown_085EFD9C); sWindowIds[TEXT_WIN_ID] = AddWindowWithoutTileMap(sWindowTemplate_Text);
SetWindowAttribute(gSaveFailedWindowIds[TEXT_WIN_ID], 7, (u32)&gDecompressionBuffer[0x2800]); SetWindowAttribute(sWindowIds[TEXT_WIN_ID], 7, (u32)&gDecompressionBuffer[0x2800]);
gSaveFailedWindowIds[CLOCK_WIN_ID] = AddWindowWithoutTileMap(gUnknown_085EFDA4); sWindowIds[CLOCK_WIN_ID] = AddWindowWithoutTileMap(sWindowTemplate_Clock);
SetWindowAttribute(gSaveFailedWindowIds[CLOCK_WIN_ID], 7, (u32)&gDecompressionBuffer[0x3D00]); SetWindowAttribute(sWindowIds[CLOCK_WIN_ID], 7, (u32)&gDecompressionBuffer[0x3D00]);
DeactivateAllTextPrinters(); DeactivateAllTextPrinters();
ResetSpriteData(); ResetSpriteData();
ResetTasks(); ResetTasks();
@ -229,12 +218,12 @@ static void CB2_SaveFailedScreen(void)
LoadPalette(sSaveFailedClockPal, 0x100, 0x20); LoadPalette(sSaveFailedClockPal, 0x100, 0x20);
LoadPalette(gTextWindowFrame1_Pal, 0xE0, 0x20); LoadPalette(gTextWindowFrame1_Pal, 0xE0, 0x20);
LoadPalette(gUnknown_0860F074, 0xF0, 0x20); LoadPalette(gUnknown_0860F074, 0xF0, 0x20);
DrawStdFrameWithCustomTileAndPalette(gSaveFailedWindowIds[TEXT_WIN_ID], FALSE, 0x214, 0xE); DrawStdFrameWithCustomTileAndPalette(sWindowIds[TEXT_WIN_ID], FALSE, 0x214, 0xE);
DrawStdFrameWithCustomTileAndPalette(gSaveFailedWindowIds[CLOCK_WIN_ID], FALSE, 0x214, 0xE); DrawStdFrameWithCustomTileAndPalette(sWindowIds[CLOCK_WIN_ID], FALSE, 0x214, 0xE);
FillWindowPixelBuffer(gSaveFailedWindowIds[CLOCK_WIN_ID], PIXEL_FILL(1)); // backwards? FillWindowPixelBuffer(sWindowIds[CLOCK_WIN_ID], PIXEL_FILL(1)); // backwards?
FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); FillWindowPixelBuffer(sWindowIds[TEXT_WIN_ID], PIXEL_FILL(1));
CopyWindowToVram(gSaveFailedWindowIds[CLOCK_WIN_ID], 2); // again? CopyWindowToVram(sWindowIds[CLOCK_WIN_ID], 2); // again?
CopyWindowToVram(gSaveFailedWindowIds[TEXT_WIN_ID], 1); CopyWindowToVram(sWindowIds[TEXT_WIN_ID], 1);
SaveFailedScreenTextPrint(gText_SaveFailedCheckingBackup, 1, 0); SaveFailedScreenTextPrint(gText_SaveFailedCheckingBackup, 1, 0);
BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK); BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK);
EnableInterrupts(1); EnableInterrupts(1);
@ -259,25 +248,25 @@ static void CB2_WipeSave(void)
{ {
u8 wipeTries = 0; u8 wipeTries = 0;
gSaveFailedClockInfo[CLOCK_RUNNING] = TRUE; sClockInfo[CLOCK_RUNNING] = TRUE;
while (gDamagedSaveSectors != 0 && wipeTries < 3) 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); SaveFailedScreenTextPrint(gText_BackupMemoryDamaged, 1, 0);
SetMainCallback2(CB2_GameplayCannotBeContinued); SetMainCallback2(CB2_GameplayCannotBeContinued);
return; return;
} }
FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); FillWindowPixelBuffer(sWindowIds[TEXT_WIN_ID], PIXEL_FILL(1));
SaveFailedScreenTextPrint(gText_CheckCompleted, 1, 0); SaveFailedScreenTextPrint(gText_CheckCompleted, 1, 0);
HandleSavingData(gSaveFailedType); HandleSavingData(sSaveFailedType);
if (gDamagedSaveSectors != 0) if (gDamagedSaveSectors != 0)
{ {
FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); FillWindowPixelBuffer(sWindowIds[TEXT_WIN_ID], PIXEL_FILL(1));
SaveFailedScreenTextPrint(gText_SaveFailedCheckingBackup, 1, 0); SaveFailedScreenTextPrint(gText_SaveFailedCheckingBackup, 1, 0);
} }
@ -286,12 +275,12 @@ static void CB2_WipeSave(void)
if (wipeTries == 3) if (wipeTries == 3)
{ {
FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); FillWindowPixelBuffer(sWindowIds[TEXT_WIN_ID], PIXEL_FILL(1));
SaveFailedScreenTextPrint(gText_BackupMemoryDamaged, 1, 0); SaveFailedScreenTextPrint(gText_BackupMemoryDamaged, 1, 0);
} }
else else
{ {
FillWindowPixelBuffer(gSaveFailedWindowIds[TEXT_WIN_ID], PIXEL_FILL(1)); FillWindowPixelBuffer(sWindowIds[TEXT_WIN_ID], PIXEL_FILL(1));
if (gGameContinueCallback == NULL) if (gGameContinueCallback == NULL)
SaveFailedScreenTextPrint(gText_SaveCompleteGameCannotContinue, 1, 0); SaveFailedScreenTextPrint(gText_SaveCompleteGameCannotContinue, 1, 0);
@ -304,11 +293,11 @@ static void CB2_WipeSave(void)
static void CB2_GameplayCannotBeContinued(void) static void CB2_GameplayCannotBeContinued(void)
{ {
gSaveFailedClockInfo[CLOCK_RUNNING] = FALSE; sClockInfo[CLOCK_RUNNING] = FALSE;
if (JOY_NEW(A_BUTTON)) 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); SaveFailedScreenTextPrint(gText_GamePlayCannotBeContinued, 1, 0);
SetVBlankCallback(VBlankCB); SetVBlankCallback(VBlankCB);
SetMainCallback2(CB2_FadeAndReturnToTitleScreen); SetMainCallback2(CB2_FadeAndReturnToTitleScreen);
@ -317,7 +306,7 @@ static void CB2_GameplayCannotBeContinued(void)
static void CB2_FadeAndReturnToTitleScreen(void) static void CB2_FadeAndReturnToTitleScreen(void)
{ {
gSaveFailedClockInfo[CLOCK_RUNNING] = FALSE; sClockInfo[CLOCK_RUNNING] = FALSE;
if (JOY_NEW(A_BUTTON)) if (JOY_NEW(A_BUTTON))
{ {
@ -351,7 +340,7 @@ static void VBlankCB_UpdateClockGraphics(void)
gMain.oamBuffer[0].x = 112; gMain.oamBuffer[0].x = 112;
gMain.oamBuffer[0].y = (CLOCK_WIN_TOP + 1) * 8; 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].tileNum = sClockFrames[n][0];
gMain.oamBuffer[0].matrixNum = (sClockFrames[n][2] << 4) | (sClockFrames[n][1] << 3); 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); CpuFastCopy(gMain.oamBuffer, (void *)OAM, 4);
if (gSaveFailedClockInfo[DEBUG_TIMER]) if (sClockInfo[DEBUG_TIMER])
gSaveFailedClockInfo[DEBUG_TIMER]--; sClockInfo[DEBUG_TIMER]--;
} }
static bool8 VerifySectorWipe(u16 sector) static bool8 VerifySectorWipe(u16 sector)
@ -372,7 +361,7 @@ static bool8 VerifySectorWipe(u16 sector)
u32 *ptr = (u32 *)&gSaveDataBuffer; u32 *ptr = (u32 *)&gSaveDataBuffer;
u16 i; u16 i;
ReadFlash(sector, 0, (u8 *)ptr, 4096); ReadFlash(sector, 0, (u8 *)ptr, SECTOR_SIZE);
for (i = 0; i < 0x400; i++, ptr++) for (i = 0; i < 0x400; i++, ptr++)
if (*ptr) if (*ptr)
@ -388,7 +377,7 @@ static bool8 WipeSector(u16 sector)
for (i = 0; failed && i < 130; i++) for (i = 0; failed && i < 130; i++)
{ {
for (j = 0; j < 0x1000; j++) for (j = 0; j < SECTOR_SIZE; j++)
ProgramFlashByte(sector, j, 0); ProgramFlashByte(sector, j, 0);
failed = VerifySectorWipe(sector); failed = VerifySectorWipe(sector);
@ -401,7 +390,7 @@ static bool8 WipeSectors(u32 sectorBits)
{ {
u16 i; u16 i;
for (i = 0; i < 0x20; i++) for (i = 0; i < SECTORS_COUNT; i++)
if ((sectorBits & (1 << i)) && !WipeSector(i)) if ((sectorBits & (1 << i)) && !WipeSector(i))
sectorBits &= ~(1 << i); sectorBits &= ~(1 << i);