diff --git a/src/audioState.h b/src/audioState.h index e853445..c3f26f1 100644 --- a/src/audioState.h +++ b/src/audioState.h @@ -1,3 +1,76 @@ #pragma once #include #include + +#pragma once +#include +#include +#include + +inline void printMp3Detail(const uint8_t type, const int value) +{ + Serial.println(); // Add a newline before printing the details + switch (type) + { + case TimeOut: + Serial.println("Time Out!"); + break; + case WrongStack: + Serial.println("Stack Wrong!"); + break; + case DFPlayerCardInserted: + Serial.println("Card Inserted!"); + break; + case DFPlayerCardRemoved: + Serial.println("Card Removed!"); + break; + case DFPlayerCardOnline: + Serial.println("Card Online!"); + break; + case DFPlayerUSBInserted: + Serial.println("USB Inserted!"); + break; + case DFPlayerUSBRemoved: + Serial.println("USB Removed!"); + break; + case DFPlayerPlayFinished: + Serial.print("Num:"); + Serial.print(value); + Serial.println(" Finished!"); + break; + case DFPlayerError: + Serial.print("DFPlayerError: "); + switch (value) + { + case Busy: + Serial.println("Card not found"); + break; + case Sleeping: + Serial.println("Sleeping"); + break; + case SerialWrongStack: + Serial.println("Wrong Stack"); + break; + case CheckSumNotMatch: + Serial.println("Checksum Error"); + break; + case FileIndexOut: + Serial.println("File Index OOB"); + break; + case FileMismatch: + Serial.println("File Mismatch"); + break; + case Advertise: + Serial.println("In Advertise"); + break; + default: + Serial.println("Unknown Error"); + break; + } + break; + default: + Serial.println("Unknown Type"); + break; + } + delay(100); +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 3c10689..6b6f09f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,6 +11,7 @@ #include "states.h" #include "timer.h" #include "audioState.h" +#include "sequences.h" #define PN532_CS 10 @@ -135,13 +136,13 @@ void loop(void) { currentLoopTime = millis(); deltaTime = currentLoopTime - lastLoopTime; - + bool doCheck = stationDetectionTimer.update(deltaTime); if (doCheck) { checkStations(); } - + stateMachine.update(Context(stations, sizeof(stations) / sizeof(stations[0]), deltaTime, &dfPlayer)); String newContent = stateMachine.updateDisplay(); if (previousDisplayContent != newContent) @@ -150,16 +151,18 @@ void loop(void) printString(newContent); previousDisplayContent = newContent; } - + lastLoopTime = currentLoopTime; delay(10); } void setup(void) { + initSequences(); setupNFC(); Serial.begin(9600); + // Serial.println(ON_MAIN_STATION.getEntryAtIndex(0)->isAudio); lcd.begin(16, 2); stationDetectionTimer.start(); diff --git a/src/sequence.cpp b/src/sequence.cpp new file mode 100644 index 0000000..419d4b0 --- /dev/null +++ b/src/sequence.cpp @@ -0,0 +1,44 @@ +#include +#include "sequence.h" + +SequenceEntry::SequenceEntry(const bool is_audio, const int duration, const int audio_id): + isAudio(is_audio), + duration(duration), + audioId(audio_id) +{ +} + +SequenceEntry* Sequence::getEntryAtIndex(const int index) const +{ + if (index >= this->length) + { + // illegal argument + return nullptr; + } + return this->entries[index]; +} + +int Sequence::getLength() const +{ + return this->length; +} + +int Sequence::getRepeatIndex() const +{ + return repeatIndex; +} + +Sequence::Sequence(const int repeatIndex): entries{}, length(0), repeatIndex(repeatIndex) +{ +} + +void Sequence::addEntry(SequenceEntry entry) +{ + if (this->length == 20) + { + // max amount of entries + return; + } + entries[length] = &entry; + length += 1; +} diff --git a/src/sequence.h b/src/sequence.h new file mode 100644 index 0000000..3757ece --- /dev/null +++ b/src/sequence.h @@ -0,0 +1,25 @@ +#pragma once +#include + +class SequenceEntry { +public: + SequenceEntry(bool is_audio, int duration, int audio_id); + + bool isAudio; + int duration; + int audioId; +}; + +class Sequence { +private: + SequenceEntry* entries[20]; + int length; + int repeatIndex; +public: + explicit Sequence(int repeatIndex); + + SequenceEntry* getEntryAtIndex(int index) const; + int getLength() const; + int getRepeatIndex() const; + void addEntry(SequenceEntry entry); +}; diff --git a/src/sequences.cpp b/src/sequences.cpp new file mode 100644 index 0000000..38a9968 --- /dev/null +++ b/src/sequences.cpp @@ -0,0 +1,21 @@ +#include "sequences.h" +#include "sequence.h" +#include "sounds.h" + +// Define global sequences +Sequence ON_MAIN_STATION(0); +Sequence AFTER_MAIN_STATION(0); +Sequence HACKING_STATION_MUHVELLA(0); +Sequence AFTER_MUHVELLA(0); +Sequence HACKING_STATION_MAGIE(0); +Sequence AFTER_MAGIE(0); +Sequence HACKING_STATION_BICOLA(0); +Sequence AFTER_BICOLA(0); +Sequence HACKING_STATION_TOBIONE(0); +Sequence AFTER_TOBIONE(0); + +void initSequences() { + ON_MAIN_STATION.addEntry(SequenceEntry(true, 1000, IDLE)); + ON_MAIN_STATION.addEntry(SequenceEntry(false, 3000, 0)); + ON_MAIN_STATION.addEntry(SequenceEntry(true, 1000, IDLE)); +} \ No newline at end of file diff --git a/src/sequences.h b/src/sequences.h new file mode 100644 index 0000000..d2c9690 --- /dev/null +++ b/src/sequences.h @@ -0,0 +1,16 @@ +#pragma once +#include "sequences.h" +#include "sequence.h" + +extern Sequence ON_MAIN_STATION; +extern Sequence AFTER_MAIN_STATION; +extern Sequence HACKING_STATION_MUHVELLA; +extern Sequence AFTER_MUHVELLA; +extern Sequence HACKING_STATION_MAGIE; +extern Sequence AFTER_MAGIE; +extern Sequence HACKING_STATION_BICOLA; +extern Sequence AFTER_BICOLA; +extern Sequence HACKING_STATION_TOBIONE; +extern Sequence AFTER_TOBIONE; + +void initSequences(); diff --git a/src/sounds.h b/src/sounds.h index f48acd2..8ae16ad 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -1,5 +1,6 @@ #include +#define NONE 0 #define IDLE 1 #define WRONG_SIDE_STATION 2 #define TIMER_DOWN 3 diff --git a/src/state.h b/src/state.h index 5d0b1d7..7615be1 100644 --- a/src/state.h +++ b/src/state.h @@ -1,19 +1,73 @@ #pragma once +#include +#include + #include "station.h" #include "context.h" +#include "sequence.h" class Station; class State { +private: + Timer sequenceTimer; + bool currentEntryHandled; + +protected: + Sequence* sequence; + int sequencePointer; + bool sequenceDone; + public: virtual ~State() = default; + explicit State(Sequence* sequence): sequenceTimer(Timer(0, false)), currentEntryHandled(false), sequence(sequence), + sequencePointer(0), sequenceDone(false) + { + } + virtual State* pickedUp(Context context) { return this; } virtual State* putDown(Context context, Station* newStation) { return this; } virtual State* update(Context context) { return this; } - virtual void activated(Context context) { } + virtual void activated(Context context) + { + } virtual String updateDisplay() { return ""; } + + void updateSeqence(const Context& context) + { + if (sequence == nullptr || sequence->getLength() == 0) + { + return; + } + if (!currentEntryHandled) + { + const auto currentEntry = sequence->getEntryAtIndex(sequencePointer); + const auto addressInt = reinterpret_cast(currentEntry); + this->sequenceTimer = Timer(currentEntry->duration, false); + this->sequenceTimer.start(); + if (currentEntry->isAudio) + { + // printMp3Detail(context.dfPlayer->readType(), context.dfPlayer->read()); + context.dfPlayer->play(currentEntry->audioId); + } + currentEntryHandled = true; + } + const bool timeOut = this->sequenceTimer.update(context.delta); + if (timeOut) + { + if (this->sequencePointer + 2 >= this->sequence->getLength()) + { + sequencePointer = sequence->getRepeatIndex(); + sequenceDone = true; + currentEntryHandled = false; + return; + } + this->sequencePointer += 1; + currentEntryHandled = false; + } + } }; diff --git a/src/states.cpp b/src/states.cpp index 51bcf15..e717945 100644 --- a/src/states.cpp +++ b/src/states.cpp @@ -1,9 +1,14 @@ #include "states.h" + +#include + #include "state.h" #include "station.h" #include "sounds.h" -Startup::Startup() = default; +Startup::Startup(): State(nullptr) +{ +} State* Startup::putDown(const Context context, Station* newStation) { @@ -16,8 +21,9 @@ State* Startup::putDown(const Context context, Station* newStation) return this; } -State* Startup::update(Context context) +State* Startup::update(const Context context) { + updateSeqence(context); return this; } @@ -35,15 +41,20 @@ void Startup::activated(Context context) //------------------------------------ -WaitingForGameStart::WaitingForGameStart() = default; +WaitingForGameStart::WaitingForGameStart() : State(&ON_MAIN_STATION) +{ +} State* WaitingForGameStart::pickedUp(const Context context) { - return new OnTheMove(context.stations + 1); // first element of the array + return new OnTheMove(context.stations + 1, &AFTER_MAIN_STATION); // first element of the array } -State* WaitingForGameStart::update(Context context) +State* WaitingForGameStart::update(const Context context) { + // Serial.println("update wait"); + updateSeqence(context); + // Serial.println("after"); return this; } @@ -62,7 +73,7 @@ void WaitingForGameStart::activated(const Context context) //------------------------------------ -OnTheMove::OnTheMove(Station* targetStation) +OnTheMove::OnTheMove(Station* targetStation, Sequence* sequence): State(sequence) { this->targetStation = targetStation; } @@ -75,7 +86,7 @@ State* OnTheMove::putDown(const Context context, Station* newStation) { return new End(); } - return new Hacking(this->targetStation); + return new Hacking(this->targetStation, nullptr); } return new IncorrectStation(targetStation); @@ -83,6 +94,7 @@ State* OnTheMove::putDown(const Context context, Station* newStation) State* OnTheMove::update(const Context context) { + updateSeqence(context); return this; } @@ -96,10 +108,11 @@ void OnTheMove::activated(const Context context) const int index = context.getStationIndex(this->targetStation); if (index == 1) { - context.dfPlayer->play(REMOVED_FROM_MAIN_STATION); - } else + context.dfPlayer->play(REMOVED_FROM_MAIN_STATION); + } + else { - context.dfPlayer->play(REMOVED_FROM_SIDE_STATION); + context.dfPlayer->play(REMOVED_FROM_SIDE_STATION); } } @@ -107,18 +120,19 @@ void OnTheMove::activated(const Context context) //------------------------------------ -IncorrectStation::IncorrectStation(Station* targetStation) +IncorrectStation::IncorrectStation(Station* targetStation): State(nullptr) // todo remove nullptr { this->targetStation = targetStation; } State* IncorrectStation::pickedUp(const Context context) { - return new OnTheMove(this->targetStation); + return new OnTheMove(this->targetStation, nullptr); // todo fix nullptr } State* IncorrectStation::update(const Context context) { + updateSeqence(context); return this; } @@ -135,7 +149,7 @@ void IncorrectStation::activated(Context context) //------------------------------------ -Hacking::Hacking(Station* currentStation): timer(5000, false) +Hacking::Hacking(Station* currentStation, Sequence* sequence): State(sequence), timer(5000, false) { this->currentStation = currentStation; this->timer.start(); @@ -148,15 +162,16 @@ State* Hacking::pickedUp(const Context context) State* Hacking::update(const Context context) { + updateSeqence(context); Serial.println(String(context.delta)); const bool done = timer.update(context.delta); - + if (done) { const int currentStationIndex = context.getStationIndex(currentStation); const int nextStationIndex = (currentStationIndex + 1) % context.stationCount; Station* nextStation = context.stations + nextStationIndex; - return new WaitingForPickup(currentStation, nextStation); + return new WaitingForPickup(currentStation, nextStation, nullptr); } return this; } @@ -175,7 +190,7 @@ void Hacking::activated(const Context context) //------------------------------------ -Complain::Complain(Station* currentStation) +Complain::Complain(Station* currentStation): State(nullptr) { this->currentStation = currentStation; } @@ -184,7 +199,7 @@ State* Complain::putDown(const Context context, Station* newStation) { if (this->currentStation == newStation) // was put back on correct station { - return new Hacking(this->currentStation); + return new Hacking(this->currentStation, nullptr); } return this; // was not put back on correct station (just keeps complaining) } @@ -207,7 +222,7 @@ void Complain::activated(Context context) //------------------------------------ -WaitingForPickup::WaitingForPickup(Station* currentStation, Station* targetStation) +WaitingForPickup::WaitingForPickup(Station* currentStation, Station* targetStation, Sequence* sequence): State(sequence) { this->currentStation = currentStation; this->targetStation = targetStation; @@ -215,7 +230,7 @@ WaitingForPickup::WaitingForPickup(Station* currentStation, Station* targetStati State* WaitingForPickup::pickedUp(Context context) { - return new OnTheMove(targetStation); + return new OnTheMove(targetStation, nullptr); } State* WaitingForPickup::update(Context context) @@ -236,7 +251,10 @@ void WaitingForPickup::activated(Context context) //------------------------------------ -End::End() = default; +End::End():State(nullptr) +{ + +} State* End::pickedUp(const Context context) @@ -256,7 +274,7 @@ String End::updateDisplay() return "END..."; } -void End::activated(Context context) +void End::activated(const Context context) { context.dfPlayer->play(GAME_WON); } diff --git a/src/states.h b/src/states.h index f89b856..12a05d6 100644 --- a/src/states.h +++ b/src/states.h @@ -33,7 +33,7 @@ private: Station* targetStation; public: - explicit OnTheMove(Station* targetStation); + explicit OnTheMove(Station* targetStation, Sequence* sequence); State* putDown(Context context, Station* newStation) override; State* update(Context context) override; String updateDisplay() override; @@ -61,7 +61,7 @@ private: Station* currentStation; public: - explicit Hacking(Station* currentStation); + explicit Hacking(Station* currentStation, Sequence* sequence); State* pickedUp(Context context) override; State* update(Context context) override; String updateDisplay() override; @@ -88,7 +88,7 @@ private: Station* targetStation; public: - WaitingForPickup(Station* currentStation, Station* targetStation); + WaitingForPickup(Station* currentStation, Station* targetStation, Sequence* sequence); State* pickedUp(Context context) override; State* update(Context context) override; String updateDisplay() override; diff --git a/src/timer.cpp b/src/timer.cpp index 5d5c9a4..c3b12eb 100644 --- a/src/timer.cpp +++ b/src/timer.cpp @@ -16,15 +16,15 @@ void Timer::start() bool Timer::update(const unsigned long delta) { - Serial.print("Timer "); + // Serial.print("Timer "); if (!running) { - Serial.print(" not running..."); + // Serial.print(" not running..."); return false; } bool timedOut = false; this->currentTime += delta; - Serial.print(" target : " + String(this->currentTime) + "/" + String(this->endTime)); + // Serial.print(" target : " + String(this->currentTime) + "/" + String(this->endTime)); if (currentTime > this->endTime) { timedOut = true; @@ -37,7 +37,6 @@ bool Timer::update(const unsigned long delta) { running = false; } - Serial.println(); return timedOut; }