Get rid of selectScreen, allow clearing the screens separately, implement a PIN message function on the bottom screen (you can place a textfile named pinmessage.txt in /luma, with 800 characters max)
This commit is contained in:
parent
ffaa5790c2
commit
7952271d61
@ -119,8 +119,8 @@ void configMenu(bool oldPinStatus)
|
||||
|
||||
initScreens();
|
||||
|
||||
drawString(CONFIG_TITLE, 10, 10, COLOR_TITLE);
|
||||
drawString("Press A to select, START to save", 10, 30, COLOR_WHITE);
|
||||
drawString(CONFIG_TITLE, true, 10, 10, COLOR_TITLE);
|
||||
drawString("Press A to select, START to save", true, 10, 30, COLOR_WHITE);
|
||||
|
||||
//Character to display a selected option
|
||||
char selected = 'x';
|
||||
@ -133,8 +133,8 @@ void configMenu(bool oldPinStatus)
|
||||
if(!(i == NEWCPU && !isN3DS))
|
||||
{
|
||||
multiOptions[i].posY = endPos + SPACING_Y;
|
||||
endPos = drawString(multiOptionsText[i], 10, multiOptions[i].posY, COLOR_WHITE);
|
||||
drawCharacter(selected, 10 + multiOptions[i].posXs[multiOptions[i].enabled] * SPACING_X, multiOptions[i].posY, COLOR_WHITE);
|
||||
endPos = drawString(multiOptionsText[i], true, 10, multiOptions[i].posY, COLOR_WHITE);
|
||||
drawCharacter(selected, true, 10 + multiOptions[i].posXs[multiOptions[i].enabled] * SPACING_X, multiOptions[i].posY, COLOR_WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,8 +145,8 @@ void configMenu(bool oldPinStatus)
|
||||
for(u32 i = 0; i < singleOptionsAmount; i++)
|
||||
{
|
||||
singleOptions[i].posY = endPos + SPACING_Y;
|
||||
endPos = drawString(singleOptionsText[i], 10, singleOptions[i].posY, color);
|
||||
if(singleOptions[i].enabled) drawCharacter(selected, 10 + SPACING_X, singleOptions[i].posY, color);
|
||||
endPos = drawString(singleOptionsText[i], true, 10, singleOptions[i].posY, color);
|
||||
if(singleOptions[i].enabled) drawCharacter(selected, true, 10 + SPACING_X, singleOptions[i].posY, color);
|
||||
color = COLOR_WHITE;
|
||||
}
|
||||
|
||||
@ -191,22 +191,22 @@ void configMenu(bool oldPinStatus)
|
||||
//The user moved to a different option, print the old option in white and the new one in red. Only print 'x's if necessary
|
||||
if(oldSelectedOption < multiOptionsAmount)
|
||||
{
|
||||
drawString(multiOptionsText[oldSelectedOption], 10, multiOptions[oldSelectedOption].posY, COLOR_WHITE);
|
||||
drawCharacter(selected, 10 + multiOptions[oldSelectedOption].posXs[multiOptions[oldSelectedOption].enabled] * SPACING_X, multiOptions[oldSelectedOption].posY, COLOR_WHITE);
|
||||
drawString(multiOptionsText[oldSelectedOption], true, 10, multiOptions[oldSelectedOption].posY, COLOR_WHITE);
|
||||
drawCharacter(selected, true, 10 + multiOptions[oldSelectedOption].posXs[multiOptions[oldSelectedOption].enabled] * SPACING_X, multiOptions[oldSelectedOption].posY, COLOR_WHITE);
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 singleOldSelected = oldSelectedOption - multiOptionsAmount;
|
||||
drawString(singleOptionsText[singleOldSelected], 10, singleOptions[singleOldSelected].posY, COLOR_WHITE);
|
||||
if(singleOptions[singleOldSelected].enabled) drawCharacter(selected, 10 + SPACING_X, singleOptions[singleOldSelected].posY, COLOR_WHITE);
|
||||
drawString(singleOptionsText[singleOldSelected], true, 10, singleOptions[singleOldSelected].posY, COLOR_WHITE);
|
||||
if(singleOptions[singleOldSelected].enabled) drawCharacter(selected, true, 10 + SPACING_X, singleOptions[singleOldSelected].posY, COLOR_WHITE);
|
||||
}
|
||||
|
||||
if(selectedOption < multiOptionsAmount)
|
||||
drawString(multiOptionsText[selectedOption], 10, multiOptions[selectedOption].posY, COLOR_RED);
|
||||
drawString(multiOptionsText[selectedOption], true, 10, multiOptions[selectedOption].posY, COLOR_RED);
|
||||
else
|
||||
{
|
||||
u32 singleSelected = selectedOption - multiOptionsAmount;
|
||||
drawString(singleOptionsText[singleSelected], 10, singleOptions[singleSelected].posY, COLOR_RED);
|
||||
drawString(singleOptionsText[singleSelected], true, 10, singleOptions[singleSelected].posY, COLOR_RED);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -215,7 +215,7 @@ void configMenu(bool oldPinStatus)
|
||||
if(selectedOption < multiOptionsAmount)
|
||||
{
|
||||
u32 oldEnabled = multiOptions[selectedOption].enabled;
|
||||
drawCharacter(selected, 10 + multiOptions[selectedOption].posXs[oldEnabled] * SPACING_X, multiOptions[selectedOption].posY, COLOR_BLACK);
|
||||
drawCharacter(selected, true, 10 + multiOptions[selectedOption].posXs[oldEnabled] * SPACING_X, multiOptions[selectedOption].posY, COLOR_BLACK);
|
||||
multiOptions[selectedOption].enabled = (oldEnabled == 3 || !multiOptions[selectedOption].posXs[oldEnabled + 1]) ? 0 : oldEnabled + 1;
|
||||
|
||||
if(selectedOption == BRIGHTNESS) updateBrightness(multiOptions[BRIGHTNESS].enabled);
|
||||
@ -224,17 +224,17 @@ void configMenu(bool oldPinStatus)
|
||||
{
|
||||
bool oldEnabled = singleOptions[selectedOption - multiOptionsAmount].enabled;
|
||||
singleOptions[selectedOption - multiOptionsAmount].enabled = !oldEnabled;
|
||||
if(oldEnabled) drawCharacter(selected, 10 + SPACING_X, singleOptions[selectedOption - multiOptionsAmount].posY, COLOR_BLACK);
|
||||
if(oldEnabled) drawCharacter(selected, true, 10 + SPACING_X, singleOptions[selectedOption - multiOptionsAmount].posY, COLOR_BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
//In any case, if the current option is enabled (or a multiple choice option is selected) we must display a red 'x'
|
||||
if(selectedOption < multiOptionsAmount)
|
||||
drawCharacter(selected, 10 + multiOptions[selectedOption].posXs[multiOptions[selectedOption].enabled] * SPACING_X, multiOptions[selectedOption].posY, COLOR_RED);
|
||||
drawCharacter(selected, true, 10 + multiOptions[selectedOption].posXs[multiOptions[selectedOption].enabled] * SPACING_X, multiOptions[selectedOption].posY, COLOR_RED);
|
||||
else
|
||||
{
|
||||
u32 singleSelected = selectedOption - multiOptionsAmount;
|
||||
if(singleOptions[singleSelected].enabled) drawCharacter(selected, 10 + SPACING_X, singleOptions[singleSelected].posY, COLOR_RED);
|
||||
if(singleOptions[singleSelected].enabled) drawCharacter(selected, true, 10 + SPACING_X, singleOptions[singleSelected].posY, COLOR_RED);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,15 +32,13 @@
|
||||
#include "fs.h"
|
||||
#include "font.h"
|
||||
|
||||
static bool bottomScreenSelected = false;
|
||||
|
||||
bool loadSplash(void)
|
||||
{
|
||||
u32 topSplashSize = getFileSize("/luma/splash.bin"),
|
||||
bottomSplashSize = getFileSize("/luma/splashbottom.bin");
|
||||
const char *topSplashPath = "/luma/splash.bin",
|
||||
*bottomSplashPath = "/luma/splashbottom.bin";
|
||||
|
||||
bool isTopSplashValid = topSplashSize == SCREEN_TOP_FBSIZE,
|
||||
isBottomSplashValid = bottomSplashSize == SCREEN_BOTTOM_FBSIZE;
|
||||
bool isTopSplashValid = getFileSize(topSplashPath) == SCREEN_TOP_FBSIZE,
|
||||
isBottomSplashValid = getFileSize(bottomSplashPath) == SCREEN_BOTTOM_FBSIZE;
|
||||
|
||||
//Don't delay boot nor init the screens if no splash images or invalid splash images are on the SD
|
||||
if(!isTopSplashValid && !isBottomSplashValid)
|
||||
@ -48,22 +46,17 @@ bool loadSplash(void)
|
||||
|
||||
initScreens();
|
||||
|
||||
if(isTopSplashValid) fileRead(fb->top_left, "/luma/splash.bin", topSplashSize);
|
||||
if(isBottomSplashValid) fileRead(fb->bottom, "/luma/splashbottom.bin", bottomSplashSize);
|
||||
if(isTopSplashValid) fileRead(fb->top_left, topSplashPath, 0);
|
||||
if(isBottomSplashValid) fileRead(fb->bottom, bottomSplashPath, 0);
|
||||
|
||||
chrono(3);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void selectScreen(bool isBottomScreen)
|
||||
void drawCharacter(char character, bool isTopScreen, u32 posX, u32 posY, u32 color)
|
||||
{
|
||||
bottomScreenSelected = isBottomScreen;
|
||||
}
|
||||
|
||||
void drawCharacter(char character, u32 posX, u32 posY, u32 color)
|
||||
{
|
||||
u8 *const select = bottomScreenSelected ? fb->bottom : fb->top_left;
|
||||
u8 *select = isTopScreen ? fb->top_left : fb->bottom;
|
||||
|
||||
for(u32 y = 0; y < 8; y++)
|
||||
{
|
||||
@ -81,7 +74,7 @@ void drawCharacter(char character, u32 posX, u32 posY, u32 color)
|
||||
}
|
||||
}
|
||||
|
||||
u32 drawString(const char *string, u32 posX, u32 posY, u32 color)
|
||||
u32 drawString(const char *string, bool isTopScreen, u32 posX, u32 posY, u32 color)
|
||||
{
|
||||
for(u32 i = 0, line_i = 0; i < strlen(string); i++, line_i++)
|
||||
{
|
||||
@ -91,15 +84,15 @@ u32 drawString(const char *string, u32 posX, u32 posY, u32 color)
|
||||
line_i = 0;
|
||||
i++;
|
||||
}
|
||||
else if(line_i >= ((bottomScreenSelected ? SCREEN_BOTTOM_WIDTH : SCREEN_TOP_WIDTH) - posX) / SPACING_X)
|
||||
else if(line_i >= ((isTopScreen ? SCREEN_TOP_WIDTH : SCREEN_BOTTOM_WIDTH) - posX) / SPACING_X)
|
||||
{
|
||||
//Make sure we never get out of the screen
|
||||
posY += SPACING_Y;
|
||||
line_i = 2; //Little offset so we know the same string continues
|
||||
line_i = 1; //Little offset so we know the same string continues
|
||||
if(string[i] == ' ') i++; //Spaces at the start look weird
|
||||
}
|
||||
|
||||
drawCharacter(string[i], posX + line_i * SPACING_X, posY, color);
|
||||
drawCharacter(string[i], isTopScreen, posX + line_i * SPACING_X, posY, color);
|
||||
}
|
||||
|
||||
return posY;
|
||||
|
@ -45,6 +45,5 @@
|
||||
#define COLOR_YELLOW 0x00FFFF
|
||||
|
||||
bool loadSplash(void);
|
||||
void selectScreen(bool isBottomScreen);
|
||||
void drawCharacter(char character, u32 posX, u32 posY, u32 color);
|
||||
u32 drawString(const char *string, u32 posX, u32 posY, u32 color);
|
||||
void drawCharacter(char character, bool isTopScreen, u32 posX, u32 posY, u32 color);
|
||||
u32 drawString(const char *string, bool isTopScreen, u32 posX, u32 posY, u32 color);
|
@ -107,25 +107,25 @@ void detectAndProcessExceptionDumps(void)
|
||||
|
||||
initScreens();
|
||||
|
||||
drawString("An exception occurred", 10, 10, COLOR_RED);
|
||||
u32 posY = drawString(dumpHeader->processor == 11 ? "Processor: ARM11 (core )" : "Processor: ARM9", 10, 30, COLOR_WHITE);
|
||||
if(dumpHeader->processor == 11) drawCharacter('0' + dumpHeader->core, 10 + 29 * SPACING_X, 30, COLOR_WHITE);
|
||||
drawString("An exception occurred", true, 10, 10, COLOR_RED);
|
||||
u32 posY = drawString(dumpHeader->processor == 11 ? "Processor: ARM11 (core )" : "Processor: ARM9", true, 10, 30, COLOR_WHITE);
|
||||
if(dumpHeader->processor == 11) drawCharacter('0' + dumpHeader->core, true, 10 + 29 * SPACING_X, 30, COLOR_WHITE);
|
||||
|
||||
posY = drawString("Exception type: ", 10, posY + SPACING_Y, COLOR_WHITE);
|
||||
drawString(handledExceptionNames[dumpHeader->type], 10 + 17 * SPACING_X, posY, COLOR_WHITE);
|
||||
posY = drawString("Exception type: ", true, 10, posY + SPACING_Y, COLOR_WHITE);
|
||||
drawString(handledExceptionNames[dumpHeader->type], true, 10 + 17 * SPACING_X, posY, COLOR_WHITE);
|
||||
|
||||
if(dumpHeader->type == 2)
|
||||
{
|
||||
if((regs[16] & 0x20) == 0 && dumpHeader->codeDumpSize >= 4)
|
||||
{
|
||||
u32 instr = *(vu32 *)(stackDump - 4);
|
||||
if(instr == 0xE12FFF7E) drawString(specialExceptions[0], 10 + 32 * SPACING_X, posY, COLOR_WHITE);
|
||||
else if(instr == 0xEF00003C) drawString(specialExceptions[1], 10 + 32 * SPACING_X, posY, COLOR_WHITE);
|
||||
if(instr == 0xE12FFF7E) drawString(specialExceptions[0], true, 10 + 32 * SPACING_X, posY, COLOR_WHITE);
|
||||
else if(instr == 0xEF00003C) drawString(specialExceptions[1], true, 10 + 32 * SPACING_X, posY, COLOR_WHITE);
|
||||
}
|
||||
else if((regs[16] & 0x20) == 0 && dumpHeader->codeDumpSize >= 2)
|
||||
{
|
||||
u16 instr = *(vu16 *)(stackDump - 2);
|
||||
if(instr == 0xDF3C) drawString(specialExceptions[1], 10 + 32 * SPACING_X, posY, COLOR_WHITE);
|
||||
if(instr == 0xDF3C) drawString(specialExceptions[1], true, 10 + 32 * SPACING_X, posY, COLOR_WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,22 +133,22 @@ void detectAndProcessExceptionDumps(void)
|
||||
{
|
||||
char processName[] = "Current process: ";
|
||||
memcpy(processName + sizeof(processName) - 9, (void *)additionalData, 8);
|
||||
posY = drawString(processName, 10, posY + SPACING_Y, COLOR_WHITE);
|
||||
posY = drawString(processName, true, 10, posY + SPACING_Y, COLOR_WHITE);
|
||||
}
|
||||
|
||||
posY += SPACING_Y;
|
||||
|
||||
for(u32 i = 0; i < 17; i += 2)
|
||||
{
|
||||
posY = drawString(registerNames[i], 10, posY + SPACING_Y, COLOR_WHITE);
|
||||
posY = drawString(registerNames[i], true, 10, posY + SPACING_Y, COLOR_WHITE);
|
||||
hexItoa(regs[i], hexString, 8);
|
||||
drawString(hexString, 10 + 7 * SPACING_X, posY, COLOR_WHITE);
|
||||
drawString(hexString, true, 10 + 7 * SPACING_X, posY, COLOR_WHITE);
|
||||
|
||||
if(i != 16 || dumpHeader->processor != 9)
|
||||
{
|
||||
drawString(registerNames[i + 1], 10 + 22 * SPACING_X, posY, COLOR_WHITE);
|
||||
drawString(registerNames[i + 1], true, 10 + 22 * SPACING_X, posY, COLOR_WHITE);
|
||||
hexItoa(i == 16 ? regs[20] : regs[i + 1], hexString, 8);
|
||||
drawString(hexString, 10 + 29 * SPACING_X, posY, COLOR_WHITE);
|
||||
drawString(hexString, true, 10 + 29 * SPACING_X, posY, COLOR_WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,28 +156,24 @@ void detectAndProcessExceptionDumps(void)
|
||||
|
||||
u32 mode = regs[16] & 0xF;
|
||||
if(dumpHeader->type == 3 && (mode == 7 || mode == 11))
|
||||
posY = drawString("Incorrect dump: failed to dump code and/or stack", 10, posY + SPACING_Y, COLOR_YELLOW) + SPACING_Y;
|
||||
posY = drawString("Incorrect dump: failed to dump code and/or stack", true, 10, posY + SPACING_Y, COLOR_YELLOW) + SPACING_Y;
|
||||
|
||||
selectScreen(true);
|
||||
|
||||
u32 posYBottom = drawString("Stack dump:", 10, 10, COLOR_WHITE) + SPACING_Y;
|
||||
u32 posYBottom = drawString("Stack dump:", false, 10, 10, COLOR_WHITE) + SPACING_Y;
|
||||
|
||||
for(u32 line = 0; line < 19 && stackDump < additionalData; line++)
|
||||
{
|
||||
hexItoa(regs[13] + 8 * line, hexString, 8);
|
||||
posYBottom = drawString(hexString, 10, posYBottom + SPACING_Y, COLOR_WHITE);
|
||||
drawCharacter(':', 10 + 8 * SPACING_X, posYBottom, COLOR_WHITE);
|
||||
posYBottom = drawString(hexString, false, 10, posYBottom + SPACING_Y, COLOR_WHITE);
|
||||
drawCharacter(':', false, 10 + 8 * SPACING_X, posYBottom, COLOR_WHITE);
|
||||
|
||||
for(u32 i = 0; i < 8 && stackDump < additionalData; i++, stackDump++)
|
||||
{
|
||||
char byteString[] = "00";
|
||||
hexItoa(*stackDump, byteString, 2);
|
||||
drawString(byteString, 10 + 10 * SPACING_X + 3 * i * SPACING_X, posYBottom, COLOR_WHITE);
|
||||
drawString(byteString, false, 10 + 10 * SPACING_X + 3 * i * SPACING_X, posYBottom, COLOR_WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
selectScreen(false);
|
||||
|
||||
char path[42];
|
||||
char fileName[] = "crash_dump_00000000.dmp";
|
||||
const char *pathFolder = dumpHeader->processor == 9 ? "/luma/dumps/arm9" : "/luma/dumps/arm11";
|
||||
@ -189,12 +185,12 @@ void detectAndProcessExceptionDumps(void)
|
||||
|
||||
if(fileWrite((void *)dumpHeader, path, dumpHeader->totalSize))
|
||||
{
|
||||
posY = drawString("You can find a dump in the following file:", 10, posY + SPACING_Y, COLOR_WHITE);
|
||||
posY = drawString(path, 10, posY + SPACING_Y, COLOR_WHITE) + SPACING_Y;
|
||||
posY = drawString("You can find a dump in the following file:", true, 10, posY + SPACING_Y, COLOR_WHITE);
|
||||
posY = drawString(path, true, 10, posY + SPACING_Y, COLOR_WHITE) + SPACING_Y;
|
||||
}
|
||||
else posY = drawString("Error writing the dump file", 10, posY + SPACING_Y, COLOR_RED);
|
||||
else posY = drawString("Error writing the dump file", true, 10, posY + SPACING_Y, COLOR_RED);
|
||||
|
||||
drawString("Press any button to shutdown", 10, posY + SPACING_Y, COLOR_WHITE);
|
||||
drawString("Press any button to shutdown", true, 10, posY + SPACING_Y, COLOR_WHITE);
|
||||
|
||||
memset32((void *)dumpHeader, 0, dumpHeader->totalSize);
|
||||
|
||||
|
35
source/pin.c
35
source/pin.c
@ -46,14 +46,14 @@ static char pinKeyToLetter(u32 pressed)
|
||||
|
||||
void newPin(bool allowSkipping)
|
||||
{
|
||||
clearScreens();
|
||||
clearScreens(true, true);
|
||||
|
||||
u8 length = 4 + 2 * (MULTICONFIG(PIN) - 1);
|
||||
|
||||
char *title = allowSkipping ? "Press START to skip or enter a new PIN" : "Enter a new PIN to proceed";
|
||||
drawString(title, 10, 10, COLOR_TITLE);
|
||||
drawString("PIN ( digits): ", 10, 10 + 2 * SPACING_Y, COLOR_WHITE);
|
||||
drawCharacter('0' + length, 10 + 5 * SPACING_X, 10 + 2 * SPACING_Y, COLOR_WHITE);
|
||||
drawString(title, true, 10, 10, COLOR_TITLE);
|
||||
drawString("PIN ( digits): ", true, 10, 10 + 2 * SPACING_Y, COLOR_WHITE);
|
||||
drawCharacter('0' + length, true, 10 + 5 * SPACING_X, 10 + 2 * SPACING_Y, COLOR_WHITE);
|
||||
|
||||
//Pad to AES block length with zeroes
|
||||
u8 __attribute__((aligned(4))) enteredPassword[0x10] = {0};
|
||||
@ -80,7 +80,7 @@ void newPin(bool allowSkipping)
|
||||
enteredPassword[cnt++] = (u8)key; //Add character to password
|
||||
|
||||
//Visualize character on screen
|
||||
drawCharacter(key, 10 + charDrawPos, 10 + 2 * SPACING_Y, COLOR_WHITE);
|
||||
drawCharacter(key, true, 10 + charDrawPos, 10 + 2 * SPACING_Y, COLOR_WHITE);
|
||||
charDrawPos += 2 * SPACING_X;
|
||||
}
|
||||
|
||||
@ -132,11 +132,24 @@ bool verifyPin(void)
|
||||
u8 cnt = 0;
|
||||
int charDrawPos = 16 * SPACING_X;
|
||||
|
||||
const char *messagePath = "/luma/pinmessage.txt";
|
||||
|
||||
u32 messageSize = getFileSize(messagePath);
|
||||
if(messageSize > 0 && messageSize < 800)
|
||||
{
|
||||
char message[messageSize + 1];
|
||||
|
||||
fileRead(message, messagePath, 0);
|
||||
message[messageSize] = 0;
|
||||
|
||||
drawString(message, false, 10, 10, COLOR_WHITE);
|
||||
}
|
||||
|
||||
while(!unlock)
|
||||
{
|
||||
drawString("Press START to shutdown or enter PIN to proceed", 10, 10, COLOR_TITLE);
|
||||
drawString("PIN ( digits): ", 10, 10 + 2 * SPACING_Y, COLOR_WHITE);
|
||||
drawCharacter('0' + pin.length, 10 + 5 * SPACING_X, 10 + 2 * SPACING_Y, COLOR_WHITE);
|
||||
drawString("Press START to shutdown or enter PIN to proceed", true, 10, 10, COLOR_TITLE);
|
||||
drawString("PIN ( digits): ", true, 10, 10 + 2 * SPACING_Y, COLOR_WHITE);
|
||||
drawCharacter('0' + pin.length, true, 10 + 5 * SPACING_X, 10 + 2 * SPACING_Y, COLOR_WHITE);
|
||||
|
||||
u32 pressed;
|
||||
do
|
||||
@ -155,7 +168,7 @@ bool verifyPin(void)
|
||||
enteredPassword[cnt++] = (u8)key; //Add character to password
|
||||
|
||||
//Visualize character on screen
|
||||
drawCharacter(key, 10 + charDrawPos, 10 + 2 * SPACING_Y, COLOR_WHITE);
|
||||
drawCharacter(key, true, 10 + charDrawPos, 10 + 2 * SPACING_Y, COLOR_WHITE);
|
||||
charDrawPos += 2 * SPACING_X;
|
||||
|
||||
if(cnt >= pin.length)
|
||||
@ -168,9 +181,9 @@ bool verifyPin(void)
|
||||
charDrawPos = 16 * SPACING_X;
|
||||
cnt = 0;
|
||||
|
||||
clearScreens();
|
||||
clearScreens(true, false);
|
||||
|
||||
drawString("Wrong PIN, try again", 10, 10 + 4 * SPACING_Y, COLOR_RED);
|
||||
drawString("Wrong PIN, try again", true, 10, 10 + 4 * SPACING_Y, COLOR_RED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -101,29 +101,42 @@ void updateBrightness(u32 brightnessIndex)
|
||||
invokeArm11Function(ARM11);
|
||||
}
|
||||
|
||||
void clearScreens(void)
|
||||
{
|
||||
void clearScreens(bool clearTop, bool clearBottom)
|
||||
{
|
||||
static bool clearTopTmp,
|
||||
clearBottomTmp;
|
||||
clearTopTmp = clearTop;
|
||||
clearBottomTmp = clearBottom;
|
||||
|
||||
void __attribute__((naked)) ARM11(void)
|
||||
{
|
||||
//Disable interrupts
|
||||
__asm(".word 0xF10C01C0");
|
||||
|
||||
//Setting up two simultaneous memory fills using the GPU
|
||||
vu32 *REGs_PSC0 = (vu32 *)0x10400010;
|
||||
REGs_PSC0[0] = (u32)fb->top_left >> 3; //Start address
|
||||
REGs_PSC0[1] = (u32)(fb->top_left + SCREEN_TOP_FBSIZE) >> 3; //End address
|
||||
REGs_PSC0[2] = 0; //Fill value
|
||||
REGs_PSC0[3] = (2 << 8) | 1; //32-bit pattern; start
|
||||
|
||||
vu32 *REGs_PSC1 = (vu32 *)0x10400020;
|
||||
REGs_PSC1[0] = (u32)fb->bottom >> 3; //Start address
|
||||
REGs_PSC1[1] = (u32)(fb->bottom + SCREEN_BOTTOM_FBSIZE) >> 3; //End address
|
||||
REGs_PSC1[2] = 0; //Fill value
|
||||
REGs_PSC1[3] = (2 << 8) | 1; //32-bit pattern; start
|
||||
vu32 *REGs_PSC0 = (vu32 *)0x10400010,
|
||||
*REGs_PSC1 = (vu32 *)0x10400020;
|
||||
|
||||
while(!((REGs_PSC0[3] & 2) && (REGs_PSC1[3] & 2)));
|
||||
if(clearTopTmp)
|
||||
{
|
||||
REGs_PSC0[0] = (u32)fb->top_left >> 3; //Start address
|
||||
REGs_PSC0[1] = (u32)(fb->top_left + SCREEN_TOP_FBSIZE) >> 3; //End address
|
||||
REGs_PSC0[2] = 0; //Fill value
|
||||
REGs_PSC0[3] = (2 << 8) | 1; //32-bit pattern; start
|
||||
}
|
||||
|
||||
if(fb->top_right != fb->top_left)
|
||||
if(clearBottomTmp)
|
||||
{
|
||||
REGs_PSC1[0] = (u32)fb->bottom >> 3; //Start address
|
||||
REGs_PSC1[1] = (u32)(fb->bottom + SCREEN_BOTTOM_FBSIZE) >> 3; //End address
|
||||
REGs_PSC1[2] = 0; //Fill value
|
||||
REGs_PSC1[3] = (2 << 8) | 1; //32-bit pattern; start
|
||||
}
|
||||
|
||||
while(!((!clearTopTmp || (REGs_PSC0[3] & 2)) && (!clearBottomTmp || (REGs_PSC1[3] & 2))));
|
||||
|
||||
if(fb->top_right != fb->top_left && clearTopTmp)
|
||||
{
|
||||
REGs_PSC0[0] = (u32)fb->top_right >> 3; //Start address
|
||||
REGs_PSC0[1] = (u32)(fb->top_right + SCREEN_TOP_FBSIZE) >> 3; //End address
|
||||
@ -136,6 +149,8 @@ void clearScreens(void)
|
||||
WAIT_FOR_ARM9();
|
||||
}
|
||||
|
||||
flushDCacheRange(&clearTopTmp, 1);
|
||||
flushDCacheRange(&clearBottomTmp, 1);
|
||||
flushDCacheRange((void *)fb, sizeof(struct fb));
|
||||
invokeArm11Function(ARM11);
|
||||
}
|
||||
@ -246,14 +261,14 @@ void initScreens(void)
|
||||
flushDCacheRange((void *)fb, sizeof(struct fb));
|
||||
invokeArm11Function(ARM11);
|
||||
|
||||
clearScreens();
|
||||
clearScreens(true, true);
|
||||
|
||||
//Turn on backlight
|
||||
i2cWriteRegister(I2C_DEV_MCU, 0x22, 0x2A);
|
||||
}
|
||||
else
|
||||
{
|
||||
clearScreens();
|
||||
clearScreens(true, true);
|
||||
updateBrightness(MULTICONFIG(BRIGHTNESS));
|
||||
}
|
||||
}
|
@ -42,5 +42,5 @@ static volatile struct fb {
|
||||
|
||||
void deinitScreens(void);
|
||||
void updateBrightness(u32 brightnessIndex);
|
||||
void clearScreens(void);
|
||||
void clearScreens(bool clearTop, bool clearBottom);
|
||||
void initScreens(void);
|
@ -56,7 +56,7 @@ u32 waitInput(void)
|
||||
|
||||
void mcuReboot(void)
|
||||
{
|
||||
if(!isFirmlaunch && PDN_GPU_CNT != 1) clearScreens();
|
||||
if(!isFirmlaunch && PDN_GPU_CNT != 1) clearScreens(true, true);
|
||||
|
||||
flushEntireDCache(); //Ensure that all memory transfers have completed and that the data cache has been flushed
|
||||
|
||||
@ -66,7 +66,7 @@ void mcuReboot(void)
|
||||
|
||||
void mcuPowerOff(void)
|
||||
{
|
||||
if(!isFirmlaunch && PDN_GPU_CNT != 1) clearScreens();
|
||||
if(!isFirmlaunch && PDN_GPU_CNT != 1) clearScreens(true, true);
|
||||
|
||||
flushEntireDCache(); //Ensure that all memory transfers have completed and that the data cache has been flushed
|
||||
|
||||
@ -115,9 +115,9 @@ void error(const char *message)
|
||||
{
|
||||
initScreens();
|
||||
|
||||
drawString("An error has occurred:", 10, 10, COLOR_RED);
|
||||
u32 posY = drawString(message, 10, 30, COLOR_WHITE);
|
||||
drawString("Press any button to shutdown", 10, posY + 2 * SPACING_Y, COLOR_WHITE);
|
||||
drawString("An error has occurred:", true, 10, 10, COLOR_RED);
|
||||
u32 posY = drawString(message, true, 10, 30, COLOR_WHITE);
|
||||
drawString("Press any button to shutdown", true, 10, posY + 2 * SPACING_Y, COLOR_WHITE);
|
||||
|
||||
waitInput();
|
||||
mcuPowerOff();
|
||||
|
Reference in New Issue
Block a user