GameCounter/Source/src/screen/menu.c

155 lines
2.8 KiB
C

#include "menu.h"
#include <stdint.h>
#include <stdlib.h>
#include <ssd1306xled.h>
#include "../../lib/ssd1306xled/font6x8.h"
#include "state.h"
#include "../buttons.h"
#include "../power.h"
#include "counter.h"
#define MenuItemReset 0
#define MenuItemCancel 1
#define MenuCount MenuItemCancel + 1
uint8_t currentIndex = 0;
uint8_t lastDrawnIndex = MenuCount;
// Forward declarations
void drawMenu();
void drawMenuItem(uint8_t itemIndex, char* caption);
void selectMenuItem();
void closeMenu();
void ssd1306_string_inverted(char *s);
void ssd1306_char_inverted(char ch);
void handleMenuScreen()
{
if (button_is_pressed_or_repeated(&buttonUp))
{
if (currentIndex >= MenuCount - 1)
currentIndex = 0;
else
currentIndex++;
}
else if (button_is_pressed_or_repeated(&buttonDown))
{
if (currentIndex <= 0)
currentIndex = MenuCount - 1;
else
currentIndex--;
}
else if (button_is_released(&buttonOption))
{
selectMenuItem();
return;
}
uint8_t invalidated = getScreenInvalidated();
if (currentIndex != lastDrawnIndex || invalidated)
{
if (invalidated)
ssd1306_clear();
drawMenu();
lastDrawnIndex = currentIndex;
}
}
void drawMenu()
{
// Since there are only two items at the moment, they're always going to be
// involved in the change, so simply repaint them.
drawMenuItem(MenuItemReset, "Reset ");
drawMenuItem(MenuItemCancel, "Cancel ");
// Can't use sprintf because that'll use up more than the
// space we have left on the ATTiny.
uint8_t intPart = vcc / 1000;
if (intPart > 9) intPart = 9;
uint8_t floatPart = (vcc % 1000) / 10;
char statusText[22] = "Battery: 0-00- \0";
itoa(intPart, &statusText[9], 10);
if (floatPart <= 9)
itoa(floatPart, &statusText[12], 10);
else
itoa(floatPart, &statusText[11], 10);
// itoa adds a \0 character
statusText[10] = '.';
statusText[13] = 'v';
ssd1306_setpos(0, 7);
ssd1306_string(statusText);
}
void drawMenuItem(uint8_t itemIndex, char* caption)
{
ssd1306_setpos(0, itemIndex);
if (itemIndex == currentIndex)
ssd1306_string_inverted(caption);
else
ssd1306_string(caption);
}
void selectMenuItem()
{
switch (currentIndex)
{
case MenuItemReset:
resetCounter();
closeMenu();
break;
case MenuItemCancel:
closeMenu();
break;
}
}
void closeMenu()
{
// Reset everything for the next time
currentIndex = 0;
lastDrawnIndex = MenuCount;
setCurrentScreen(Counter);
}
void ssd1306_string_inverted(char *s)
{
while (*s)
{
ssd1306_char_inverted(*s++);
}
}
void ssd1306_char_inverted(char ch)
{
uint8_t c = ch - 32;
ssd1306_send_data_start();
for (uint8_t i = 0; i < 6; i++)
{
ssd1306_send_byte(~pgm_read_byte(&ssd1306xled_font6x8[c * 6 + i]));
}
ssd1306_send_data_stop();
}