diff --git a/src/BASICS.h b/src/BASICS.h index 7e66f39..e71cef4 100644 --- a/src/BASICS.h +++ b/src/BASICS.h @@ -6,6 +6,24 @@ #define X true #define _ false -typedef unsigned long millis_t; +typedef int64_t microseconds_t; + +double step(double valueCurrent, double valueMin, double valueMax, microseconds_t timeTotal, microseconds_t timeDelta) { + double valueRange = valueMax - valueMin; + double timeRatio = (double) timeDelta / (double) timeTotal; + double valueStep = valueRange * timeRatio; + double valueNew = max(valueMin, min(valueMax, valueCurrent + valueStep)); +// Serial.printf("valueCurrent: %13.3f\n", valueCurrent); +// Serial.printf("valueMin: %13.3f\n", valueMin); +// Serial.printf("valueMax: %13.3f\n", valueMax); +// Serial.printf("valueRange: %13.3f\n", valueRange); +// Serial.printf("timeTotal: %13.3f\n", (double) timeTotal); +// Serial.printf("timeDelta: %13.3f\n", (double) timeDelta); +// Serial.printf("timeRatio: %13.3f\n", timeRatio); +// Serial.printf("valueStep: %13.3f\n", valueStep); +// Serial.printf("valueNew: %13.3f\n", valueNew); +// Serial.println(); + return valueNew; +} #endif diff --git a/src/main.cpp b/src/main.cpp index 9329dbe..253bc9a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,5 @@ #include +#include #include "mode/Mode.h" #include "mode/GameOfLife/GameOfLife.h" #include "display/Display.h" @@ -12,7 +13,7 @@ enum ModeId { BORDER, CLOCK, GAME_OF_LIFE_BLACK_WHITE, - GAME_OF_LIFE_WHITE_FADE, + GAME_OF_LIFE_GRAYSCALE, GAME_OF_LIFE_COLOR_FADE, GAME_OF_LIFE_RANDOM_COLOR, PONG, @@ -21,11 +22,11 @@ enum ModeId { Display display(32, 8); -ModeId newModeId = SPACE_INVADERS; +ModeId newModeId = GAME_OF_LIFE_GRAYSCALE; ModeId currentModeId = NONE; -millis_t lastMillis = 0; +microseconds_t lastMicros = 0; Mode *mode = nullptr; @@ -48,17 +49,19 @@ void setup() { Serial.begin(115200); Serial.println("\n\n\nStartup!"); WiFi.begin("HappyNet", "1Grausame!Sackratte7"); + ArduinoOTA.begin(); display.setup(); } void setSpeed(double value); void loop() { + ArduinoOTA.handle(); bool hasIp = (uint32_t) WiFi.localIP() != 0; if (!connected) { if (hasIp) { connected = true; - Serial.println("WiFi connected!"); + Serial.printf("WiFi connected: %s\n", WiFi.localIP().toString().c_str()); configTime(3600, 3600, WiFi.gatewayIP().toString().c_str()); } } else { @@ -108,7 +111,7 @@ void setBrightness(int value) { } void setSpeed(double value) { - speed = min(1000.0, max(0.001, value)); + speed = value; Serial.printf("Setting speed to %6.2fx\n", value); } @@ -129,7 +132,7 @@ void unloadOldMode() { void loadNewMode() { currentModeId = newModeId; - lastMillis = 0; + lastMicros = 0; switch (currentModeId) { case NONE: break; @@ -142,7 +145,7 @@ void loadNewMode() { case GAME_OF_LIFE_BLACK_WHITE: mode = new GameOfLife(&display, BLACK_WHITE); break; - case GAME_OF_LIFE_WHITE_FADE: + case GAME_OF_LIFE_GRAYSCALE: mode = new GameOfLife(&display, GRAYSCALE); break; case GAME_OF_LIFE_COLOR_FADE: @@ -165,8 +168,8 @@ void stepMode() { if (mode == nullptr) { return; } - millis_t currentMillis = millis(); - millis_t dt = currentMillis - lastMillis; - lastMillis = currentMillis; - mode->step((millis_t) max(1.0, (double) dt * speed)); + auto currentMicros = (int64_t) micros(); + microseconds_t dt = (microseconds_t) min(1000000.0, max(1.0, (double) (currentMicros - lastMicros) * speed)); + lastMicros = currentMicros; + mode->step(dt); } diff --git a/src/mode/Clock/Clock.h b/src/mode/Clock/Clock.h index e9cd4d4..18d66b9 100644 --- a/src/mode/Clock/Clock.h +++ b/src/mode/Clock/Clock.h @@ -100,7 +100,7 @@ public: return "Clock"; } - void step(millis_t dt) override { + void step(microseconds_t dt) override { tm time{}; getLocalTime(&time); display->clear(); diff --git a/src/mode/GameOfLife/Cell.h b/src/mode/GameOfLife/Cell.h index cee8f6a..3b33d5a 100644 --- a/src/mode/GameOfLife/Cell.h +++ b/src/mode/GameOfLife/Cell.h @@ -13,12 +13,18 @@ public: uint32_t color = 0; - void animate(double per255Points) { + void animate(microseconds_t dt) { + // TODO "step" does not work as expected if (alive) { - fade = min(255.0, fade + per255Points); + fade = step(fade, 0.0, 255.0, 200000, +dt); } else { - fade = max(0.0, fade - per255Points); + fade = step(fade, 0.0, 255.0, 200000, -dt); } +// if (alive) { +// fade = min(255.0, fade + (double) dt / 200000.0); +// } else { +// fade = max(0.0, fade - (double) dt / 200000.0); +// } } uint8_t getR() const { diff --git a/src/mode/GameOfLife/GameOfLife.h b/src/mode/GameOfLife/GameOfLife.h index 59e5f54..1e4eb53 100644 --- a/src/mode/GameOfLife/GameOfLife.h +++ b/src/mode/GameOfLife/GameOfLife.h @@ -15,7 +15,7 @@ private: ColorMode colorMode; - millis_t runtime = 0; + microseconds_t runtime = 0; uint8_t steps = 0; @@ -69,9 +69,9 @@ public: return "???"; } - void step(millis_t dt) override { + void step(microseconds_t dt) override { runtime += dt; - if (runtime >= 500) { + if (runtime >= 500000) { runtime = 0; if (lastAliveCount == aliveCount) { isSteadyCount++; @@ -150,7 +150,7 @@ private: } } - void animate(millis_t dt) { + void animate(microseconds_t dt) { Cell *cell = cells; for (int y = 0; y < display->height; y++) { for (int x = 0; x < display->width; x++) { diff --git a/src/mode/Mode.h b/src/mode/Mode.h index be9c1a3..7830062 100644 --- a/src/mode/Mode.h +++ b/src/mode/Mode.h @@ -10,6 +10,8 @@ protected: Display *display; + microseconds_t clock; + public: explicit Mode(Display *display) : @@ -21,7 +23,7 @@ public: virtual const char *getName() = 0; - virtual void step(millis_t dt) = 0; + virtual void step(microseconds_t dt) = 0; }; #endif diff --git a/src/mode/Pong/Pong.h b/src/mode/Pong/Pong.h index ca24ca8..183db84 100644 --- a/src/mode/Pong/Pong.h +++ b/src/mode/Pong/Pong.h @@ -36,7 +36,7 @@ public: return "Pong"; } - void step(millis_t dt) override { + void step(microseconds_t dt) override { } diff --git a/src/mode/SpaceInvaders/SpaceInvaders.h b/src/mode/SpaceInvaders/SpaceInvaders.h index bff3d84..e19306a 100644 --- a/src/mode/SpaceInvaders/SpaceInvaders.h +++ b/src/mode/SpaceInvaders/SpaceInvaders.h @@ -22,7 +22,7 @@ class SpaceInvaders : public Mode { private: - millis_t heroRuntime = 0; + microseconds_t heroRuntime = 0; uint8_t heroX = 0; bool heroLeft = false; uint8_t heroShoot = 0; @@ -31,7 +31,7 @@ private: uint8_t invadersCountY; uint8_t invadersAlive = 0; - millis_t swarmRuntime = 0; + microseconds_t swarmRuntime = 0; uint8_t swarmY = 0; bool swarmLeft = false; bool swarmDown = false; @@ -39,7 +39,7 @@ private: Invader *swarmBegin; Invader *swarmEnd; - millis_t rocketRuntime = 0; + microseconds_t rocketRuntime = 0; Rocket *rocketsBegin; Rocket *rocketsEnd; @@ -68,7 +68,7 @@ public: return "Space Invaders"; } - void step(millis_t dt) override { + void step(microseconds_t dt) override { stepRockets(dt); stepInvaders(dt); stepHero(dt); @@ -86,10 +86,10 @@ public: } } - void stepRockets(millis_t dt) { + void stepRockets(microseconds_t dt) { rocketRuntime += dt; - if (rocketRuntime > 200) { - rocketRuntime -= 200; + if (rocketRuntime > 200000) { + rocketRuntime -= 200000; for (Rocket *rocket = rocketsBegin; rocket < rocketsEnd; rocket++) { if (rocket->alive) { if (rocket->y == 0) { @@ -108,16 +108,16 @@ public: } } - void stepInvaders(millis_t dt) { + void stepInvaders(microseconds_t dt) { swarmRuntime += dt; - if (swarmDown && swarmRuntime > 500) { + if (swarmDown && swarmRuntime > 500000) { swarmDown = false; swarmY++; } - if (swarmRuntime >= 1000) { - swarmRuntime -= 1000; + if (swarmRuntime >= 1000000) { + swarmRuntime -= 1000000; if (swarmLeft) { swarmX--; if (swarmX == 0) { @@ -135,10 +135,10 @@ public: } } - void stepHero(millis_t dt) { + void stepHero(microseconds_t dt) { heroRuntime += dt; - if (heroRuntime >= 50) { - heroRuntime -= 50; + if (heroRuntime >= 50000) { + heroRuntime -= 50000; if (heroLeft) { heroX--; if (heroX <= 1) { diff --git a/src/mode/Test/Border.h b/src/mode/Test/Border.h index b4a942c..84a5f73 100644 --- a/src/mode/Test/Border.h +++ b/src/mode/Test/Border.h @@ -18,7 +18,7 @@ public: return "Border"; } - void step(millis_t dt) override { + void step(microseconds_t dt) override { for (int y = 0; y < display->height; y++) { for (int x = 0; x < display->width; x++) { if (x == 0 || x == display->width - 1 || y == 0 || y == display->height - 1) {