Newer
Older
uwuboot / source / arm9 / menu_options.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "types.h"
#include "mem_map.h"
#include "arm9/console.h"
#include "arm9/dev.h"
#include "fatfs/ff.h"
#include "pxi.h"
#include "hid.h"
#include "util.h"
#include "arm9/main.h"
#include "arm9/timer.h"
#include "arm9/menu.h"
#include "arm9/config.h"


#define MAX_SUBOPTIONS		3

static const char *optionStrings[] = {
	"Change Boot Mode",
	"Test 1234",
	"hi profi",
	"dummy 3",
	"dummy 42424242424242424242",
	"dummy 55",
	"dummy 6",
};

static char optionSubStrings[MAX_SUBOPTIONS][0x20];

static unsigned int curOptionIndex;
static unsigned int curSubOptionIndex;
static unsigned int curHighlightedSubOptionIndex;
static bool			curSubOptionHighlighted;
static unsigned int curSubOptionCount;
static bool subOptionsActive;
static const unsigned int OptionCount = arrayEntries(optionStrings);
static int consoleX, consoleY;

void calcConsoleMetrics(void);
void rewindConsole(void);
void rewindConsoleX(void);
void handleBootMode(void);

bool menuOptions(void)
{
	u32 keys;
	
	PXI_sendWord(PXI_CMD_ALLOW_POWER_OFF);
	
	clearConsoles();
	consoleSelect(&con_bottom);
	
	calcConsoleMetrics();
	
	curOptionIndex = 0;
	curSubOptionIndex = 0;
	curHighlightedSubOptionIndex = 0;
	curSubOptionCount = 0;
	subOptionsActive = false;
	curSubOptionHighlighted = false;
	
	for(;;)
	{
		
		/* Draw screen */
		
		rewindConsole();
		
		for(unsigned int i=0; i<OptionCount + MAX_SUBOPTIONS; i++)
		{
			if(i<OptionCount)
			{
				printf("%s %s", i == curOptionIndex ? "*" : " ", optionStrings[i]);
				rewindConsoleX();
			
				if(subOptionsActive && i == curOptionIndex)
				{
					for(unsigned int j=0; j<curSubOptionCount; j++)
					{
						if(curSubOptionHighlighted && j == curHighlightedSubOptionIndex)
							printf(" %s  \x1B[33m%s\e[0m", j == curSubOptionIndex ? "*" : " ",
															optionSubStrings[j]);
						else
							printf(" %s  %s", j == curSubOptionIndex ? "*" : " ", optionSubStrings[j]);
						rewindConsoleX();
					}
				}
			}
			else
			{
				rewindConsoleX();
			}
		}
		
		
		/* Handle HID */
		
		hidScanInput();
		keys = hidKeysDown();
		
		if(keys & KEY_DUP || keys & KEY_DLEFT)
		{
			if(subOptionsActive)
			{
				if(curSubOptionIndex != 0)
					curSubOptionIndex --;
			}
			else
			{
				if(curOptionIndex != 0)
					curOptionIndex --;
			}
		}
		
		else if(keys & KEY_DDOWN || keys & KEY_DRIGHT)
		{
			if(subOptionsActive)
			{
				if(curSubOptionIndex < curSubOptionCount - 1)
					curSubOptionIndex ++;
			}
			else
			{
				if(curOptionIndex < OptionCount - 1)
					curOptionIndex ++;
			}
		}
		
		else if(keys & KEY_A)
		{
			switch(curOptionIndex)
			{
				case 0:	// "Change Boot Mode"
					handleBootMode();
					break;
				
				default:
					break;
			}
			
			if(!subOptionsActive)
			{
				subOptionsActive = true;
				curSubOptionIndex = 0;
			}
		}
		
		else if(keys & KEY_B)
		{
			if(subOptionsActive)
			{
				subOptionsActive = false;
				curSubOptionCount = 0;
			}
			else
			{
				goto done;
			}
		}
		
		switch(menuUpdateGlobalState())
		{
			case MENU_EVENT_HOME_PRESSED:
			case MENU_EVENT_POWER_PRESSED:
			case MENU_EVENT_SD_CARD_REMOVED:
			case MENU_EVENT_STATE_CHANGE:
				goto done;
			default:
				break;
		}

		menuActState();
	}

done:

	menuActState();
	menuSetReturnToState(STATE_PREVIOUS);
	
	return true;
}

void calcConsoleMetrics(void)
{
	int longestLen = 0;
	int curLen;
	const int maxLen = con_bottom.windowWidth;
	
	for(unsigned int i=0; i<arrayEntries(optionStrings); i++)
	{
		if((curLen = strlen(optionStrings[i])) > longestLen)
			longestLen = curLen;
	}
	
	consoleX = (maxLen - longestLen) / 2;
	consoleY = (con_bottom.windowHeight - arrayEntries(optionStrings) - MAX_SUBOPTIONS) / 2;
}

void rewindConsole(void)
{
	consoleSetCursor(&con_bottom, consoleX, consoleY);
}

void rewindConsoleX(void)
{
	unsigned int len = con_bottom.windowWidth - con_bottom.cursorX;
	if(len) len--;
	while(len--) printf(" ");
	
	consoleSetCursor(&con_bottom, consoleX, con_bottom.cursorY + 1);
}

void handleBootMode(void)
{
	if(subOptionsActive)
	{
		u32 mode = (u32) curSubOptionIndex;
		configSetKeyData(KBootMode, &mode);
		curHighlightedSubOptionIndex = curSubOptionIndex;
		curSubOptionHighlighted = true;
	}
	else
	{
		u32 *mode = (u32 *)configGetData(KBootMode);
		if(mode)
		{
			curHighlightedSubOptionIndex = *mode;
			curSubOptionHighlighted = true;
		}
		else curSubOptionHighlighted = false;
		
		strcpy(optionSubStrings[0], "Normal");
		strcpy(optionSubStrings[1], "Quick Boot");
		strcpy(optionSubStrings[2], "Quiet Boot");
		curSubOptionCount = 3;
	}
}