Turns out you need to drive the YL-3 constantly so implement a disp mgr

This commit is contained in:
Mikko Ahlroth 2019-10-26 13:34:20 +03:00
parent 7ac56da7ce
commit b3a6c2299d
8 changed files with 126 additions and 44 deletions

View file

@ -1,18 +1,19 @@
#include "src/debugger.hpp"
#include "src/display_manager.hpp"
#include "src/game_manager.hpp"
#include "src/randomiser.hpp"
#include "src/yl3.hpp"
Input* input;
Randomiser* randomiser;
GameManager* game;
DisplayManager* displayManager;
void setup() {
initDebug(9600);
YL3::initDisplay();
input = new Input();
randomiser = new Randomiser(analogRead(0));
game = new GameManager(input, randomiser);
displayManager = new DisplayManager();
game = new GameManager(input, randomiser, displayManager);
}
void loop() { game->loop(); }

View file

@ -50,7 +50,7 @@ const auto DELAY_DECREMENT = [](uint16_t delay) -> uint16_t {
/**
* Maximum amount of beeps you can be "behind" before the game is stopped.
*/
const uint8_t MAX_WAITING = 10;
const uint8_t MAX_WAITING = 20;
/**
* RCK (latch) pin of YL3 display.

49
src/display_manager.cpp Normal file
View file

@ -0,0 +1,49 @@
#include "display_manager.hpp"
#include <Arduino.h>
#include "yl3.hpp"
DisplayManager::DisplayManager() : currentIndex(0), currentDisplay(""), currentDisplayLength(0) {
YL3::initDisplay();
}
void DisplayManager::clearDisplay() {
YL3::clearDisplay();
currentDisplay = "";
currentIndex = 0;
currentDisplayLength = 0;
}
void DisplayManager::drawText(const String text) {
clearDisplay();
const auto length = text.length();
currentDisplay = text;
currentDisplayLength = length;
currentIndex = 0;
}
void DisplayManager::drawNumber(const uint32_t number) {
const auto str = String(number);
drawText(str);
}
void DisplayManager::loop() {
if (currentDisplayLength == 0) {
return;
}
const char c = currentDisplay.charAt(currentIndex);
uint8_t i = currentIndex;
if (currentDisplayLength > 8) {
i = currentIndex - 8;
}
YL3::drawChar(currentDisplayLength - 1 - i, c);
++currentIndex;
if (currentIndex >= currentDisplayLength) {
currentIndex = 0;
}
}

41
src/display_manager.hpp Normal file
View file

@ -0,0 +1,41 @@
#include <Arduino.h>
#pragma once
/**
* Display manager for the YL3 8x7-segment display.
*
* The YL3 can only display one digit at a time, in as many positions as needed. Usually though we
* need to display many digits in different positions. This display manager will keep in memory the
* displayable text and display one digit at a time, flickering the display fast enough so that the
* user doesn't notice.
*/
class DisplayManager {
uint8_t currentIndex;
String currentDisplay;
uint8_t currentDisplayLength;
public:
DisplayManager();
/**
* Clear display entirely.
*/
void clearDisplay();
/**
* Draw text on the screen, right aligned. Text longer than 8 characters will be truncated.
*/
void drawText(const String text);
/**
* Draw a number on the screen, right aligned. Numbers larger than can fit on the display will be
* truncated.
*/
void drawNumber(const uint32_t number);
/**
* Draw character and advance to next one for next loop.
*/
void loop();
};

View file

@ -4,30 +4,36 @@
#include "base_game.hpp"
#include "config.hpp"
#include "debugger.hpp"
#include "display_manager.hpp"
#include "input.hpp"
#include "randomiser.hpp"
#include "speed_game.hpp"
#include "yl3.hpp"
GameManager::GameManager(Input* input, Randomiser* randomiser)
: input(input), randomiser(randomiser), state(State::GAME), currentScore(0) {
GameManager::GameManager(Input* input, Randomiser* randomiser, DisplayManager* displayManager)
: input(input),
randomiser(randomiser),
displayManager(displayManager),
state(State::GAME),
currentScore(0) {
debugPrint("Initialising new game...");
currentGame = new SpeedGame(randomiser);
YL3::clearDisplay();
displayManager->clearDisplay();
}
void GameManager::loop() {
displayManager->loop();
if (state == State::GAME) {
auto nextOp = currentGame->loop();
if (nextOp.type == NextOperationType::ADD_SCORE) {
currentScore += nextOp.scoreToAdd;
debugPrint("Added score!");
YL3::drawNumber(currentScore);
displayManager->drawNumber(currentScore);
} else if (nextOp.type == NextOperationType::END) {
debugPrint("Game ended.");
state = State::SCORE;
YL3::drawText("END");
displayManager->drawText("END");
}
}
}

View file

@ -1,5 +1,6 @@
#include "base_game.hpp"
#include "config.hpp"
#include "display_manager.hpp"
#include "input.hpp"
#include "randomiser.hpp"
@ -10,12 +11,13 @@ enum class State { MENU, INIT, GAME, SCORE };
class GameManager {
Input* input;
Randomiser* randomiser;
DisplayManager* displayManager;
State state;
uint16_t currentScore;
BaseGame* currentGame;
public:
GameManager(Input* input, Randomiser* randomiser);
GameManager(Input* input, Randomiser* randomiser, DisplayManager* displayManager);
void loop();
};

View file

@ -28,31 +28,15 @@ void YL3::initDisplay() {
void YL3::clearDisplay() {
drawBegin();
shiftOut(YL3_DIO, YL3_SCK, MSBFIRST, 0b11111111);
shiftOut(YL3_DIO, YL3_SCK, MSBFIRST, ALL);
shiftOut(YL3_DIO, YL3_SCK, MSBFIRST, EMPTY);
drawEnd();
}
void YL3::drawText(const String text) {
clearDisplay();
const auto length = text.length();
uint8_t i = 0;
if (length > 8) {
i = length - 8;
}
for (; i < length; ++i) {
drawBegin();
const auto b = char2byte(text.charAt(i));
shiftOut(YL3_DIO, YL3_SCK, MSBFIRST, INDICES[length - 1 - i]);
shiftOut(YL3_DIO, YL3_SCK, MSBFIRST, b);
drawEnd();
}
}
void YL3::drawNumber(const uint32_t score) {
const auto str = String(score);
drawText(str);
void YL3::drawChar(const uint8_t index, const char c) {
drawBegin();
const auto b = char2byte(c);
shiftOut(YL3_DIO, YL3_SCK, MSBFIRST, INDICES[index]);
shiftOut(YL3_DIO, YL3_SCK, MSBFIRST, b);
drawEnd();
}

View file

@ -35,9 +35,9 @@ const byte CHARS[] = {
0b10010000, // 9
0b10001000, // A
0b10000011, // B
0b10111001, // C
0b11000110, // C
0b10100001, // D
0b10110000, // E
0b10000110, // E
0b10001110, // F
0b10000010, // G
0b10001001, // H
@ -68,6 +68,11 @@ const byte CHARS[] = {
const byte INDICES[] = {0b10000000, 0b01000000, 0b00100000, 0b00010000,
0b00001000, 0b00000100, 0b00000010, 0b00000001};
/**
* Index that refers to all positions.
*/
const byte ALL = 0b11111111;
/**
* Empty byte to clear display.
*/
@ -99,14 +104,8 @@ void initDisplay();
void clearDisplay();
/**
* Draw text on the screen, right aligned. Text longer than 8 characters will be truncated.
* Draw character on the screen in given index.
*/
void drawText(const String text);
/**
* Draw a number on the screen, right aligned. Numbers larger than can fit on the display will be
* truncated.
*/
void drawNumber(const uint32_t score);
void drawChar(uint8_t index, const char c);
}; // namespace YL3