first commit

This commit is contained in:
Alejandro Guerrero 2026-09-27 17:21:39 +02:00
commit e6a42e28e9
4355 changed files with 4626605 additions and 0 deletions

View file

@ -0,0 +1,279 @@
#include <LovyanGFX.hpp>
#if defined( LGFX_M5STACK ) || defined( ARDUINO_M5Stack_Core_ESP32 ) || defined( ARDUINO_M5STACK_FIRE ) // M5Stack
#define BUTTON_A_PIN 39
#define BUTTON_B_PIN 38
static constexpr std::uint32_t draw_cycle = 3;
static constexpr float zoom_min = 2;
static constexpr float zoom_max = 32;
#elif defined( LGFX_M5STACK_CORE2 ) || defined( ARDUINO_M5STACK_Core2 )
#define BUTTON_A_PIN -1
#define BUTTON_B_PIN -1
static constexpr std::uint32_t draw_cycle = 3;
static constexpr float zoom_min = 2;
static constexpr float zoom_max = 32;
#elif defined ( LGFX_M5STICKC ) || defined ( ARDUINO_M5Stick_C )
#define BUTTON_A_PIN 37
#define BUTTON_B_PIN 39
static constexpr std::uint32_t draw_cycle = 1;
static constexpr float zoom_min = 1.4;
static constexpr float zoom_max = 16;
#elif defined( LGFX_ODROID_GO ) || defined( ARDUINO_ODROID_ESP32 ) // ODROID-GO
#define BUTTON_A_PIN 32
#define BUTTON_B_PIN 33
static constexpr std::uint32_t draw_cycle = 3;
static constexpr float zoom_min = 2;
static constexpr float zoom_max = 32;
#elif defined( LGFX_TTGO_TWATCH ) || defined( ARDUINO_T ) // TTGO T-Watch
#define BUTTON_A_PIN 36
#define BUTTON_B_PIN -1
static constexpr std::uint32_t draw_cycle = 2;
static constexpr float zoom_min = 2;
static constexpr float zoom_max = 32;
#elif defined( LGFX_WIO_TERMINAL ) || defined (ARDUINO_WIO_TERMINAL) || defined(WIO_TERMINAL)
#define BUTTON_A_PIN 0x0200|28
#define BUTTON_B_PIN 0x0200|27
static constexpr std::uint32_t draw_cycle = 3;
static constexpr float zoom_min = 2;
static constexpr float zoom_max = 32;
#endif
static LGFX lcd;
static LGFX_Sprite sp(&lcd);
static std::int32_t px, py;
static float ox, oy;
static float cx, cy, cr;
static float ax, ay;
static float zoom;
static float angle, rad;
static float add_angle = 0;
static float add_advance = 0;
static std::uint32_t draw_count = 0;
static std::uint32_t skip_count = 0;
static constexpr float deg_to_rad = 0.017453292519943295769236907684886;
static constexpr float gravity = -0.005;
static constexpr float zoom_speed = 0.02;
static void create_maze(void)
{
sp.clear(0);
sp.setColor(1);
sp.fillRect(0, 0, sp.width(), 16);
sp.fillRect(0, sp.height() - 16, sp.width(), 16);
sp.fillRect( 0, 0, 16, sp.height()-16);
sp.fillRect(sp.width()-16, 0, 16, sp.height()-16);
sp.setColor(3);
for (int y = 1; y < sp.height(); y += 2)
{
for (int x = 1; x < sp.width(); x += 2)
{
sp.writePixel(x, y);
int xx = x;
int yy = y;
do
{
xx = x;
yy = y;
switch (random(4)) {
case 0: xx = x + 1; break;
case 1: xx = x - 1; break;
case 2: yy = y + 1; break;
case 3: yy = y - 1; break;
}
} while (3 == sp.readPixelValue(xx, yy));
sp.writePixel(xx, yy);
}
}
}
static void draw(void)
{
draw_count += draw_cycle;
std::uint_fast8_t blink = 127+abs(((int)(draw_count<<1) & 255)-128);
sp.setPaletteColor(1, 127, 127, blink);
sp.setPaletteColor(2, 127, blink, 127);
float fx = (cx - ox);
float fy = (cy - oy);
float len = sqrtf(fx * fx + fy * fy) * zoom;
float theta = atan2f(fx, fy) + rad;
sp.pushRotateZoom(px - sinf(theta) * len, py - cosf(theta) * len, angle, zoom, zoom);
}
static void game_init(void)
{
px = lcd.width()>>1;
py = lcd.height()/3;
create_maze();
ox = sp.getPivotX();
oy = sp.getPivotY();
cx = (sp.width() >>1);
cy = (sp.height()>>1);
cr = 0.2;
zoom = zoom_min;
}
static bool game_main(void)
{
std::int32_t tx, ty, tc;
tc = lcd.getTouch(&tx, &ty);
if ((BUTTON_A_PIN >=0 && BUTTON_B_PIN >=0 && (lgfx::gpio_in(BUTTON_A_PIN) == 0 && lgfx::gpio_in(BUTTON_B_PIN) == 0)) || tc > 1)
{
zoom *= 1.0 - zoom_speed;
if (zoom < zoom_min) { zoom = zoom_min; }
}
else
{
zoom *= 1.0 + zoom_speed;
if (zoom > zoom_max) { zoom = zoom_max; }
add_angle -= add_angle / 10;
if (tc)
{
add_angle += (tx > lcd.width()>>1) ? 0.6 : -0.6;
}
else if (BUTTON_A_PIN >= 0 && BUTTON_B_PIN >= 0)
{
if (BUTTON_A_PIN >=0 && lgfx::gpio_in(BUTTON_A_PIN) == 0) add_angle += 0.6;
if (BUTTON_B_PIN >=0 && lgfx::gpio_in(BUTTON_B_PIN) == 0) add_angle -= 0.6;
}
else
{
static bool pressed;
static bool flow;
if (BUTTON_A_PIN >=0 && lgfx::gpio_in(BUTTON_A_PIN) == 0)
{
if (!pressed)
{
pressed = true;
flow = !flow;
}
add_angle += flow ? 0.6 : -0.6;
}
else
{
pressed = false;
}
}
}
angle += add_angle;
add_angle = add_angle * 9 / 10;
rad = angle * - deg_to_rad;
ax += sinf(rad) * gravity;
ay -= cosf(rad) * gravity;
ax = ax * 9.7 / 10;
ay = ay * 9.7 / 10;
float addy = (ay<0.0) ? -cr:cr;
auto tmpy = roundf(cy+ay+addy);
if ( 3 == sp.readPixelValue(roundf(cx), tmpy))
{
cy = tmpy - addy + (ay < 0.0 ? 0.5 : -0.5);
ay = -ay * 9.0 / 10;
}
else
{
cy += ay;
}
float addx = (ax<0.0) ? -cr:cr;
auto tmpx = roundf(cx+ax+addx);
if ( 3 == sp.readPixelValue(tmpx, roundf(cy)))
{
cx = tmpx - addx + (ax < 0.0 ? 0.5 : -0.5);
ax = -ax * 9.0 / 10;
}
else
{
cx += ax;
}
std::uint32_t pv = sp.readPixelValue(roundf(cx), roundf(cy));
if ( 0 == pv)
{
sp.drawPixel(roundf(cx), roundf(cy), 2);
}
else if (1 == pv) return true;
if (++skip_count == draw_cycle)
{
skip_count = 0;
draw();
}
return false;
}
void setup(void)
{
lgfx::lgfxPinMode(BUTTON_A_PIN, lgfx::pin_mode_t::input);
lgfx::lgfxPinMode(BUTTON_B_PIN, lgfx::pin_mode_t::input);
lcd.init();
lcd.startWrite();
lcd.setColorDepth(16);
sp.setColorDepth(2);
sp.createSprite(257, 257);
game_init();
}
void loop(void)
{
if (!game_main())
{
lcd.fillCircle(px, py, roundf(cr*zoom), 0xFFFF00U);
}
else
{
std::int32_t py0 = lcd.height() >> 1;
float cx0 = (cx + (sp.width() >>1)) / 2;
float cy0 = (cy + (sp.height()>>1)) / 2;
for (;;)
{
draw();
if (py < py0) ++py;
if (cx != cx0) cx += (cx0 - cx) / 256;
if (cy != cy0) cy += (cy0 - cy) / 256;
angle += .5;
rad = angle * - deg_to_rad;
zoom *= 1 - zoom_speed;
if (zoom < zoom_min)
{
std::int32_t tx, ty;
zoom = zoom_min;
if ((BUTTON_A_PIN >=0 && lgfx::gpio_in(BUTTON_A_PIN) == 0)
|| (BUTTON_B_PIN >=0 && lgfx::gpio_in(BUTTON_B_PIN) == 0)
|| lcd.getTouch(&tx, &ty)
) break;
}
}
game_init();
}
}