Add selection 'highlight', ease movement
This commit is contained in:
parent
03cb418d63
commit
bec441bd96
@ -14,6 +14,7 @@ add_executable(mtgcard
|
|||||||
src/flash.cpp
|
src/flash.cpp
|
||||||
src/cardslot.cpp
|
src/cardslot.cpp
|
||||||
src/icons.cpp
|
src/icons.cpp
|
||||||
|
src/menu.cpp
|
||||||
src/manamenu.cpp
|
src/manamenu.cpp
|
||||||
|
|
||||||
src/usb_descriptors.c
|
src/usb_descriptors.c
|
||||||
|
|||||||
@ -50,6 +50,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t current;
|
uint8_t current;
|
||||||
|
uint8_t previous;
|
||||||
bool going_left;
|
bool going_left;
|
||||||
float progress;
|
float progress;
|
||||||
};
|
};
|
||||||
|
|||||||
179
src/manamenu.cpp
179
src/manamenu.cpp
@ -9,20 +9,72 @@ namespace
|
|||||||
|
|
||||||
constexpr uint8_t COLORS[] = { 0, 0b1, 0b10, 0b100, 0b1000, 0b10000 };
|
constexpr uint8_t COLORS[] = { 0, 0b1, 0b10, 0b100, 0b1000, 0b10000 };
|
||||||
|
|
||||||
|
// adapted from easings.net
|
||||||
|
float easeInOutElastic(float x)
|
||||||
|
{
|
||||||
|
constexpr float c5 = (2 * 3.1415926f) / 4.5f;
|
||||||
|
|
||||||
|
if (x == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (x == 1)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (x < 0.5)
|
||||||
|
{
|
||||||
|
return -powf(2, 20 * x - 10) * sinf((20 * x - 11.125f) * c5) / 2.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return powf(2, -20 * x + 10) * sinf((20 * x - 11.25f) * c5) / 2.0f + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// adapted from easings.net
|
||||||
|
float easeOutElastic(float x)
|
||||||
|
{
|
||||||
|
constexpr float c4 = (2 * 3.1415926f) / 3;
|
||||||
|
|
||||||
|
if (x == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (x == 1)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return powf(2, -10 * x) * sinf((x * 10 - 0.75f) * c4) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// adapted from easings.net
|
||||||
|
float easeInElastic(float x)
|
||||||
|
{
|
||||||
|
constexpr float c4 = (2 * 3.1415926f) / 3;
|
||||||
|
|
||||||
|
if (x == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (x == 1)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -powf(2, 10 * x - 10) * sinf((x * 10 - 10.75f) * c4);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace menus;
|
using namespace menus;
|
||||||
|
|
||||||
Menu::Menu(lib::Display& display) :
|
|
||||||
display(&display)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ManaMenu::ManaMenu(lib::Display& display) :
|
ManaMenu::ManaMenu(lib::Display& display) :
|
||||||
Menu(display),
|
Menu(display),
|
||||||
current(0),
|
current(0),
|
||||||
|
previous(0),
|
||||||
going_left(false),
|
going_left(false),
|
||||||
progress(0.999f)
|
progress(0.99f)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,11 +82,51 @@ void ManaMenu::onTick(float dt)
|
|||||||
{
|
{
|
||||||
constexpr float PI = 3.1415926f;
|
constexpr float PI = 3.1415926f;
|
||||||
constexpr float STEP = 2 * PI / 6.0f;
|
constexpr float STEP = 2 * PI / 6.0f;
|
||||||
constexpr float RADIUS = 80;
|
constexpr float RADIUS = 75;
|
||||||
|
constexpr float CENTER_X = 120;
|
||||||
|
constexpr float CENTER_Y = 190;
|
||||||
|
constexpr float MAX_OFFSET = RADIUS / 1.5f;
|
||||||
|
constexpr float DT_SCALE_ROTATE = 1.1f;
|
||||||
|
constexpr float DT_SCALE_UPDOWN = 1.6f;
|
||||||
|
constexpr uint8_t ERASE_DATA[38 * 5 * 3] = {};
|
||||||
|
|
||||||
if (progress < 1.0f)
|
if (progress < 1.0f)
|
||||||
{
|
{
|
||||||
const float offset = (going_left ? -1 : 1) * STEP * progress + STEP / 2.0f;
|
const float offset
|
||||||
|
= (1.0f - easeOutElastic(progress)) * MAX_OFFSET + RADIUS;
|
||||||
|
|
||||||
|
// erase old
|
||||||
|
{
|
||||||
|
display->set_update_area(CENTER_X - 20, CENTER_Y - 20 - offset, 38, 5);
|
||||||
|
auto pixels = display->pixels();
|
||||||
|
pixels.write(ERASE_DATA, 38 * 5 * 3);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
display->set_update_area(CENTER_X - 20, CENTER_Y - 15 + 30 - offset, 38,
|
||||||
|
5);
|
||||||
|
auto pixels = display->pixels();
|
||||||
|
pixels.write(ERASE_DATA, 38 * 5 * 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write new
|
||||||
|
{
|
||||||
|
display->set_update_area(CENTER_X - 15, CENTER_Y - 15 - offset, 31, 32);
|
||||||
|
auto pixels = display->pixels();
|
||||||
|
const uint8_t* data = icon::wubrgc(COLORS[previous]);
|
||||||
|
pixels.write(data, icon::LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
progress += dt * DT_SCALE_UPDOWN;
|
||||||
|
if (progress > 0.75f)
|
||||||
|
{
|
||||||
|
progress = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (progress < 2.0f)
|
||||||
|
{
|
||||||
|
const float offset
|
||||||
|
= (going_left ? -1 : 1) * STEP * easeOutElastic(progress - 1)
|
||||||
|
+ STEP / 2.0f;
|
||||||
|
|
||||||
// erase previous
|
// erase previous
|
||||||
for (int i = 0; i < sizeof(COLORS) / sizeof(*COLORS); i++)
|
for (int i = 0; i < sizeof(COLORS) / sizeof(*COLORS); i++)
|
||||||
@ -44,54 +136,42 @@ void ManaMenu::onTick(float dt)
|
|||||||
const float x = cosf(angle) * RADIUS;
|
const float x = cosf(angle) * RADIUS;
|
||||||
const float y = sinf(angle) * RADIUS;
|
const float y = sinf(angle) * RADIUS;
|
||||||
|
|
||||||
const int left = x - 20 + 120;
|
const int left = x - 20 + CENTER_X;
|
||||||
const int top = y - 20 + 160;
|
const int top = y - 20 + CENTER_Y;
|
||||||
|
|
||||||
// top rectangle
|
// top rectangle
|
||||||
{
|
{
|
||||||
display->set_update_area(left, top, 38, 5);
|
display->set_update_area(left, top, 38, 5);
|
||||||
auto pixels = display->pixels();
|
auto pixels = display->pixels();
|
||||||
for (int pixel = 0; pixel < 38 * 5; pixel++)
|
pixels.write(ERASE_DATA, 38 * 5 * 3);
|
||||||
{
|
|
||||||
pixels.write(0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// bottom rectangle
|
// bottom rectangle
|
||||||
{
|
{
|
||||||
display->set_update_area(left, top + 36, 38, 5);
|
display->set_update_area(left, top + 36, 38, 5);
|
||||||
auto pixels = display->pixels();
|
auto pixels = display->pixels();
|
||||||
for (int pixel = 0; pixel < 38 * 5; pixel++)
|
pixels.write(ERASE_DATA, 38 * 5 * 3);
|
||||||
{
|
|
||||||
pixels.write(0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// left rectangle
|
// left rectangle
|
||||||
{
|
{
|
||||||
display->set_update_area(left, top + 3, 5, 38);
|
display->set_update_area(left, top + 3, 5, 38);
|
||||||
auto pixels = display->pixels();
|
auto pixels = display->pixels();
|
||||||
for (int pixel = 0; pixel < 5 * 38; pixel++)
|
pixels.write(ERASE_DATA, 38 * 5 * 3);
|
||||||
{
|
|
||||||
pixels.write(0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// right rectangle
|
// right rectangle
|
||||||
{
|
{
|
||||||
display->set_update_area(left + 36, top + 3, 5, 38);
|
display->set_update_area(left + 36, top + 3, 5, 38);
|
||||||
auto pixels = display->pixels();
|
auto pixels = display->pixels();
|
||||||
for (int pixel = 0; pixel < 5 * 38; pixel++)
|
pixels.write(ERASE_DATA, 38 * 5 * 3);
|
||||||
{
|
|
||||||
pixels.write(0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
progress += dt * 2.0f;
|
progress += dt * DT_SCALE_ROTATE;
|
||||||
if (progress > 1.0f)
|
if (progress > 1.75f)
|
||||||
{
|
{
|
||||||
progress = 1.0f;
|
progress = 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// write new
|
// write new
|
||||||
@ -102,28 +182,58 @@ void ManaMenu::onTick(float dt)
|
|||||||
const float x = cosf(angle) * RADIUS;
|
const float x = cosf(angle) * RADIUS;
|
||||||
const float y = sinf(angle) * RADIUS;
|
const float y = sinf(angle) * RADIUS;
|
||||||
|
|
||||||
const int left = x - 15 + 120;
|
const int left = x - 15 + CENTER_X;
|
||||||
const int top = y - 15 + 160;
|
const int top = y - 15 + CENTER_Y;
|
||||||
|
|
||||||
display->set_update_area(left, top, 31, 32);
|
display->set_update_area(left, top, 31, 32);
|
||||||
auto pixels = display->pixels();
|
auto pixels = display->pixels();
|
||||||
const uint8_t* data = icon::wubrgc(COLORS[i]);
|
const uint8_t* data = icon::wubrgc(COLORS[i]);
|
||||||
pixels.write(data, icon::LENGTH);
|
pixels.write(data, icon::LENGTH);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (progress < 3.0f)
|
||||||
|
{
|
||||||
|
const float offset = easeOutElastic(progress - 2.0f) * MAX_OFFSET + RADIUS;
|
||||||
|
|
||||||
sleep_ms(1);
|
// erase old
|
||||||
|
{
|
||||||
|
display->set_update_area(CENTER_X - 20, CENTER_Y - 20 - offset, 38, 5);
|
||||||
|
auto pixels = display->pixels();
|
||||||
|
pixels.write(ERASE_DATA, 38 * 5 * 3);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
display->set_update_area(CENTER_X - 20, CENTER_Y - 15 + 30 - offset, 38,
|
||||||
|
5);
|
||||||
|
auto pixels = display->pixels();
|
||||||
|
pixels.write(ERASE_DATA, 38 * 5 * 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write new
|
||||||
|
{
|
||||||
|
display->set_update_area(CENTER_X - 15, CENTER_Y - 15 - offset, 31, 32);
|
||||||
|
auto pixels = display->pixels();
|
||||||
|
const uint8_t* data = icon::wubrgc(COLORS[current]);
|
||||||
|
pixels.write(data, icon::LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
progress += dt * DT_SCALE_UPDOWN;
|
||||||
|
if (progress > 2.75f)
|
||||||
|
{
|
||||||
|
progress = 3.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManaMenu::onLeftPressed()
|
void ManaMenu::onLeftPressed()
|
||||||
{
|
{
|
||||||
if (progress < 1.0f)
|
if (progress < 3.0f)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
going_left = true;
|
going_left = true;
|
||||||
|
|
||||||
|
previous = current;
|
||||||
if (current == 0)
|
if (current == 0)
|
||||||
{
|
{
|
||||||
current = 5;
|
current = 5;
|
||||||
@ -142,13 +252,14 @@ void ManaMenu::onMenuHeld() {}
|
|||||||
|
|
||||||
void ManaMenu::onRightPressed()
|
void ManaMenu::onRightPressed()
|
||||||
{
|
{
|
||||||
if (progress < 1.0f)
|
if (progress < 3.0f)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
going_left = false;
|
going_left = false;
|
||||||
|
|
||||||
|
previous = current;
|
||||||
if (current == 5)
|
if (current == 5)
|
||||||
{
|
{
|
||||||
current = 0;
|
current = 0;
|
||||||
|
|||||||
6
src/menu.cpp
Normal file
6
src/menu.cpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include "menu.h"
|
||||||
|
|
||||||
|
Menu::Menu(lib::Display& display) :
|
||||||
|
display(&display)
|
||||||
|
{
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user