RGBMatrixDisplay/src/mode.cpp
2023-01-03 09:58:05 +01:00

104 lines
2.2 KiB
C++

#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/NewYear/NewYear.h"
#include "display.h"
ModeId currentModeId = NONE;
microseconds_t lastMicros = 0;
ModeBase *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 NEW_YEAR:
mode = new NewYear(&display);
break;
default:
Serial.print("No mode loaded.\n");
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 dt = (microseconds_t) min(1000000.0, max(1.0, (double) (currentMicros - lastMicros) * config.speed));
lastMicros = currentMicros;
mode->step(dt);
}