RGBMatrixDisplay/src/mode.cpp

128 lines
2.7 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/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 modeMove(int index, int x, int y) {
if (mode != nullptr) {
mode->move(index, x, y);
}
}
void modeFire(int index) {
if (mode != nullptr) {
mode->fire(index);
}
}
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);
}