#include "mode.h" #include "config.h" #include "mode/Border/Border.h" #include "mode/Clock/Clock.h" #include "mode/GameOfLife/GameOfLife.h" #include "mode/Pong/Pong.h" #include "mode/SpaceInvaders/SpaceInvaders.h" #include "mode/CountDown/CountDown.h" #include "mode/Starfield/Starfield.h" #include "mode/Matrix/Matrix.h" #include "display.h" ModeId currentModeId = NONE; microseconds_t lastMicros = 0; Mode *mode = nullptr; void unloadOldMode(); void loadNewMode(); void mode_step(); void mode_loop() { if (currentModeId != config.mode) { unloadOldMode(); loadNewMode(); } mode_step(); } void setMode(ModeId value) { if (config.mode == value) { return; } config.mode = value; config_set_dirty(); } void setSpeed(double speed) { speed = min(max(0.01, speed), 10000.0); if (config.speed == speed) { return; } config.speed = speed; config_set_dirty(); Serial.printf("Setting speed to %6.2fx\n", config.speed); } void unloadOldMode() { if (mode != nullptr) { delete mode; mode = nullptr; } display.clear(); } void loadNewMode() { currentModeId = config.mode; lastMicros = 0; switch (currentModeId) { case BORDER: mode = new Border(display); break; case CLOCK: mode = new Clock(display); break; case GAME_OF_LIFE_BLACK_WHITE: mode = new GameOfLife(display, BLACK_WHITE); break; case GAME_OF_LIFE_GRAYSCALE: mode = new GameOfLife(display, GRAYSCALE); break; case GAME_OF_LIFE_COLOR_FADE: mode = new GameOfLife(display, COLOR_FADE); break; case GAME_OF_LIFE_RANDOM_COLOR: mode = new GameOfLife(display, RANDOM_COLOR); break; case PONG: mode = new Pong(display); break; case SPACE_INVADERS: mode = new SpaceInvaders(display); break; case COUNT_DOWN: mode = new CountDown(display, false); break; case COUNT_DOWN_BARS: mode = new CountDown(display, true); break; case STARFIELD: mode = new Starfield(display); break; case MATRIX: mode = new Matrix(display); break; default: Serial.print("No mode loaded.\n"); display.clear(); break; } Serial.printf("Mode: %s\n", mode == nullptr ? "None" : mode->getName()); } void mode_step() { if (mode == nullptr) { return; } auto currentMicros = (int64_t) micros(); microseconds_t microseconds = (microseconds_t) min(1000000.0, max(1.0, (double) (currentMicros - lastMicros) * config.speed)); lastMicros = currentMicros; mode->loop(microseconds); }